/* ==========================================================================
   DigitalProfile.lk — Basic Profile Template
   The shared layout engine behind template-freelancer.html,
   template-photographer.html and template-influencer.html.

   All three files use these exact classes in the exact same order. A persona
   changes the copy, the accent and the contents of the showcase slot — never
   the structure, the spacing, the radii or the shadow depth.

   Every value comes from tokens.css. Anything accent-coloured is derived from
   the single --brand-accent variable, so the colour picker needs to change
   one property and nothing else.

   SECTIONS
     0  Primitives        icon, buttons, pills, cards
     1  Stage and frame   the centred phone preview
     2  Cover             image, tools, avatar, verified badge
     3  Identity          name, handle, role, bio
     4  Socials           the dynamic icon strip
     5  Actions           primary WhatsApp CTA + secondary
     6  Link stack        direct and expandable cards
     7  Showcase          the persona slot
     8  Footer            branded tag + NFC quick order
     9  Customiser        bottom sheet, theme + accent
    10  Lightbox + toast
    11  Motion
   ========================================================================== */


/* ==========================================================================
   0 — PRIMITIVES
   ========================================================================== */
.sprite { display: none; }

.icon {
  flex: none;
  width: 1.25em;
  height: 1.25em;
  stroke-width: 2;
  vertical-align: middle;
}
.icon--sm { width: 1em; height: 1em; }
.icon--lg { width: 1.5em; height: 1.5em; }

body.profile {
  min-height: 100vh;
  font-family: var(--font-sans);
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

/* ---- Buttons --------------------------------------------------------------
   One shape for every button on the page: same height, same radius, same
   shadow depth. Only the fill changes.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 3rem;
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  text-align: center;
  border: 1px solid transparent;
  border-radius: var(--profile-radius);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(0.99); }

/* Primary — the accent gradient, lifted on its own coloured shadow */
.btn--primary {
  color: var(--accent-on);
  background-image: var(--accent-gradient);
  box-shadow: var(--accent-shadow), var(--shadow-inset-top);
}
.btn--primary:hover { box-shadow: var(--accent-shadow-lg), var(--shadow-inset-top); }

/* WhatsApp keeps its own green, because people recognise it by colour */
.btn--whatsapp {
  color: var(--white);
  background-image: linear-gradient(140deg, var(--whatsapp-500) 0%, var(--whatsapp-600) 100%);
  box-shadow: 0 8px 18px -8px rgb(37 211 102 / 0.55), var(--shadow-inset-top);
}
.btn--whatsapp:hover { box-shadow: 0 16px 34px -12px rgb(37 211 102 / 0.6), var(--shadow-inset-top); }

.btn--ghost {
  color: var(--color-text);
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}
.btn--ghost:hover {
  border-color: var(--accent-line);
  box-shadow: var(--shadow-md);
}

.btn--sm {
  width: auto;
  min-height: 2.25rem;
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
}

/* ---- Pills ----------------------------------------------------------------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}
.pill--accent {
  color: var(--color-accent-text);
  background: var(--accent-wash);
  border-color: var(--accent-line);
}
.pill--muted {
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
}
.pill .icon { width: 0.95rem; height: 0.95rem; }

/* ---- Card -------------------------------------------------------------------
   The one card shape. Floating elevation, 1px outline, 12px radius.
   -------------------------------------------------------------------------- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--profile-radius);
  box-shadow: var(--shadow-sm);
}

.section-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}
.section-label .icon { width: 0.9rem; height: 0.9rem; }


/* ==========================================================================
   1 — STAGE AND FRAME
   On a phone the profile is the page. From tablet up it becomes a device
   preview floating on an ambient wash, which is how someone judging a
   template wants to see it.
   ========================================================================== */
.stage {
  position: relative;
  display: grid;
  justify-items: center;
  min-height: 100vh;
  isolation: isolate;
}

/* Ambient accent light behind the frame — follows the chosen colour */
.stage::before,
.stage::after {
  content: "";
  position: fixed;
  z-index: -1;
  border-radius: var(--radius-full);
  filter: blur(80px);
  opacity: 0.55;
  pointer-events: none;
}
.stage::before {
  inset-block-start: -12vh;
  inset-inline-start: -10vw;
  width: 46vw;
  height: 46vw;
  background: var(--accent-glow);
}
.stage::after {
  inset-block-end: -18vh;
  inset-inline-end: -12vw;
  width: 40vw;
  height: 40vw;
  background: var(--accent-wash);
}

/* min-width: 0 stops a grid item from being floored at its min-content size.
   Without it the code block inside the showcase widens the whole page. */
.device { width: 100%; min-width: 0; }

.screen {
  width: 100%;
  padding-block-end: var(--space-10);
  background: var(--color-bg);
}

/* Tablet and up: the sleek frame */
@media (min-width: 48rem) {
  .stage {
    align-content: center;
    padding-block: var(--space-10);
  }
  .device {
    width: var(--profile-width);
    max-width: calc(100vw - var(--space-10));
    padding: 0.6rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--profile-frame-radius);
    box-shadow: var(--shadow-float);
  }
  .screen {
    max-height: min(54rem, 88vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: calc(var(--profile-frame-radius) - 0.6rem);
    scrollbar-width: thin;
    scrollbar-color: var(--color-border-strong) transparent;
  }
  .screen::-webkit-scrollbar { width: 6px; }
  .screen::-webkit-scrollbar-thumb {
    background: var(--color-border-strong);
    border-radius: var(--radius-full);
  }

  /* The speaker slot, drawn rather than imaged */
  .device::before {
    content: "";
    display: block;
    width: 3.25rem;
    height: 0.3rem;
    margin: 0 auto var(--space-2);
    background: var(--color-border-strong);
    border-radius: var(--radius-full);
  }
}


/* ==========================================================================
   2 — COVER
   ========================================================================== */
.cover {
  position: relative;
  margin-block-end: calc(var(--profile-avatar) / 2 + var(--space-3));
}

.cover__media {
  position: relative;
  height: var(--profile-cover-h);
  overflow: hidden;
}
@media (min-width: 48rem) {
  .cover__media { border-radius: var(--radius-xl) var(--radius-xl) 0 0; }
}

.cover__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Scrim keeps the floating tool buttons readable on any photo */
.cover__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgb(var(--rgb-slate-900) / 0.42) 0%,
    rgb(var(--rgb-slate-900) / 0.08) 45%,
    rgb(var(--rgb-slate-900) / 0.3) 100%
  );
}

.cover__tools {
  position: absolute;
  inset-block-start: var(--space-3);
  inset-inline-end: var(--space-3);
  display: flex;
  gap: var(--space-2);
}

/* Floating glass buttons — the theme switcher trigger lives here */
.tool {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  color: var(--white);
  background: rgb(var(--rgb-slate-900) / 0.38);
  border: 1px solid rgb(var(--rgb-white) / 0.28);
  border-radius: var(--radius-full);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}
.tool:hover {
  transform: translateY(-2px);
  background: rgb(var(--rgb-slate-900) / 0.55);
}
.tool .icon { width: 1.05rem; height: 1.05rem; }

/* Sun shows in dark mode, moon in light — only ever one at a time */
.tool__sun { display: none; }
[data-theme="dark"] .tool__moon { display: none; }
[data-theme="dark"] .tool__sun { display: block; }

/* ---- Avatar ---------------------------------------------------------------
   Sits half over the cover edge, on a gradient ring, with its own drop
   shadow so it reads as a raised object rather than a flat circle.
   -------------------------------------------------------------------------- */
.avatar {
  position: absolute;
  inset-block-end: calc(var(--profile-avatar) / -2);
  inset-inline-start: var(--profile-gutter);
  width: var(--profile-avatar);
  height: var(--profile-avatar);
  margin: 0;
}

.avatar__ring {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: var(--profile-avatar-ring);
  background-image: var(--accent-gradient);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg), var(--accent-shadow);
}

.avatar__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-full);
  background: var(--color-surface-muted);
  display: block;
}

.avatar__badge {
  position: absolute;
  inset-block-end: 2px;
  inset-inline-end: 2px;
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  color: var(--accent-on);
  background-image: var(--accent-gradient);
  border: 2px solid var(--color-surface);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-sm);
}
.avatar__badge .icon { width: 0.85rem; height: 0.85rem; }


/* ==========================================================================
   3 — IDENTITY
   ========================================================================== */
.ident {
  padding-inline: var(--profile-gutter);
  margin-block-end: var(--space-6);
}

.ident__name {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-h4);
  font-weight: var(--weight-extrabold);
  letter-spacing: var(--tracking-tighter);
  line-height: var(--leading-tight);
}

/* The handle doubles as a copy button, which is what people actually
   want from a profile URL */
.ident__handle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-1);
  padding: var(--space-1) var(--space-2);
  margin-inline-start: calc(var(--space-2) * -1);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text-subtle);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}
.ident__handle:hover {
  color: var(--color-accent-text);
  background: var(--accent-wash);
}
.ident__handle .icon {
  width: 0.85rem;
  height: 0.85rem;
  opacity: 0.7;
}
.ident__slug { color: var(--color-text); font-weight: var(--weight-semibold); }

.ident__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-block-start: var(--space-3);
}

.ident__bio {
  /* Two lines maximum, as specified — longer bios are clamped, not cut off
     mid-layout, so the card height never changes between profiles */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-block-start: var(--space-3);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--color-text-muted);
}


/* ==========================================================================
   4 — SOCIAL STRIP
   The generator prints only the networks a profile actually has, so there is
   never an empty placeholder. If a profile has none, the strip collapses.
   ========================================================================== */
.socials {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-inline: var(--profile-gutter);
  margin-block-end: var(--space-6);
}
.socials:empty { display: none; }

.social {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  transition: transform var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.social:hover {
  transform: translateY(-2px);
  color: var(--color-accent-text);
  border-color: var(--accent-line);
  box-shadow: var(--shadow-md);
}
.social .icon { width: 1.15rem; height: 1.15rem; }


/* ==========================================================================
   5 — ACTIONS
   ========================================================================== */
.actions {
  display: grid;
  gap: var(--space-3);
  padding-inline: var(--profile-gutter);
  margin-block-end: var(--space-8);
}


/* ==========================================================================
   6 — LINK STACK
   One card shape, two behaviours: a direct link, or an expandable card that
   opens detail in place rather than sending anyone to another page.
   ========================================================================== */
.links {
  display: grid;
  gap: var(--space-3);
  padding-inline: var(--profile-gutter);
  margin-block-end: var(--space-8);
}

.link-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-4);
  text-align: start;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--profile-radius);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.link-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent-line);
  box-shadow: var(--shadow-lg);
}
.link-card:active { transform: translateY(0) scale(0.995); }

.link-card__icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--color-accent-text);
  background: var(--accent-wash);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-sm);
}
.link-card__icon .icon { width: 1.15rem; height: 1.15rem; }

.link-card__body { flex: 1; min-width: 0; }

.link-card__title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
}

.link-card__sub {
  margin-block-start: 2px;
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.link-card__go {
  flex: none;
  color: var(--color-text-subtle);
  transition: transform var(--duration-base) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.link-card:hover .link-card__go {
  color: var(--color-accent-text);
  transform: translate(2px, -2px);
}

/* Expandable variant — the chevron turns, the arrow does not travel */
.link-card[aria-expanded="true"] .link-card__go { transform: rotate(180deg); }
.link-card[aria-expanded="true"] {
  border-color: var(--accent-line);
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

/* With scripting off the panel simply stays open, so the detail is never
   locked behind a button that cannot run. With scripting on it starts
   collapsed and JS drives max-height, so it slides instead of snapping.
   Only the rows carry vertical padding, so max-height: 0 collapses exactly. */
.link-panel {
  display: grid;
  margin-block-start: -1px;
  padding: 0 var(--space-4);
  background: var(--color-surface-muted);
  border: 1px solid var(--accent-line);
  border-block-start: 0;
  border-end-start-radius: var(--profile-radius);
  border-end-end-radius: var(--profile-radius);
  overflow: hidden;
}
.js .link-panel {
  max-height: 0;
  border-color: transparent;
  transition: max-height var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
.js .link-card[aria-expanded="true"] + .link-panel { border-color: var(--accent-line); }

.link-panel__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-3);
  border-block-start: 1px solid var(--color-border);
}
.link-panel__row:first-child { border-block-start: 0; padding-block-start: var(--space-4); }
.link-panel__row:last-child { padding-block-end: var(--space-4); }

.link-panel__label {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--color-text);
}
.link-panel__note {
  display: block;
  margin-block-start: 2px;
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
}
.link-panel__value {
  flex: none;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--color-accent-text);
}


/* ==========================================================================
   7 — SHOWCASE
   The one slot that changes per persona. The frame around it does not.
   ========================================================================== */
.showcase {
  padding-inline: var(--profile-gutter);
  margin-block-end: var(--space-8);
}

/* ---- Repo card (freelancer) ----------------------------------------------- */
.repo { padding: var(--space-4); }

.repo__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.repo__name {
  flex: 1;
  min-width: 0;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.repo__name span { color: var(--color-text-subtle); font-weight: var(--weight-regular); }

.repo__desc {
  margin-block-start: var(--space-2);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--color-text-muted);
}

.repo__code {
  margin-block-start: var(--space-3);
  padding: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.7;
  color: var(--color-text-muted);
  background: var(--color-bg-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow-x: auto;
}
.repo__code .tok-key { color: var(--color-accent-text); }
.repo__code .tok-str { color: var(--color-success); }
.repo__code .tok-dim { color: var(--color-text-subtle); }

.repo__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-block-start: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
}
.repo__meta span { display: inline-flex; align-items: center; gap: var(--space-1); }
.repo__dot {
  width: 0.6rem;
  height: 0.6rem;
  background: var(--brand-accent);
  border-radius: var(--radius-full);
}

/* ---- Work list (photographer) ---------------------------------------------
   The showcase slot with no uploaded media in it. Rows are hairline separated
   rather than carded, so it never reads as a second stack of link cards. */
.work-list {
  display: grid;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--profile-radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.work {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  transition: background var(--duration-fast) var(--ease-out);
}
.work + .work { border-block-start: 1px solid var(--color-border); }
.work:hover { background: var(--accent-wash); }

.work__title {
  display: block;
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text);
}
.work__meta {
  display: block;
  margin-block-start: 2px;
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  color: var(--color-text-subtle);
}

.work .icon {
  width: 1rem;
  height: 1rem;
  color: var(--color-text-subtle);
  transition: transform var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.work:hover .icon { color: var(--color-accent-text); transform: translate(2px, -2px); }

/* ---- Stat row (media kit) -------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
}
.stat {
  padding: var(--space-3);
  text-align: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.stat__num {
  display: block;
  font-size: var(--text-lg);
  font-weight: var(--weight-extrabold);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
}
.stat__label {
  display: block;
  margin-block-start: 2px;
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

.showcase__more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-block-start: var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-accent-text);
}
.showcase__more:hover { text-decoration: underline; }


/* ==========================================================================
   8 — FOOTER
   ========================================================================== */
.foot {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding: var(--space-6) var(--profile-gutter) var(--space-4);
  border-block-start: 1px solid var(--color-border);
}

.brand-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
}
.brand-tag:hover { color: var(--color-accent-text); }
.brand-tag strong { font-weight: var(--weight-semibold); color: var(--color-text-muted); }
.brand-tag img { width: 1.1rem; height: 1.1rem; }


/* ==========================================================================
   9 — CUSTOMISER
   A bottom sheet on phones, a floating panel beside the frame on desktop.
   It holds the two things a profile owner changes: theme and accent.
   ========================================================================== */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: rgb(var(--rgb-slate-900) / 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-base) var(--ease-out),
              visibility var(--duration-base) var(--ease-out);
}
.sheet-backdrop.is-open { opacity: 1; visibility: visible; }

.sheet {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: calc(var(--z-overlay) + 1);
  padding: var(--space-3) var(--space-5) var(--space-6);
  background: var(--color-surface);
  border-block-start: 1px solid var(--color-border);
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  box-shadow: var(--shadow-float);
  translate: 0 100%;
  visibility: hidden;
  transition: translate var(--duration-base) var(--ease-out),
              visibility var(--duration-base) var(--ease-out);
}
.sheet.is-open { translate: 0 0; visibility: visible; }

.sheet__grip {
  width: 2.5rem;
  height: 0.25rem;
  margin: 0 auto var(--space-4);
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
}

.sheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--space-5);
}
.sheet__title {
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
}
.sheet__close {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
  border-radius: var(--radius-full);
  cursor: pointer;
}
.sheet__close:hover { color: var(--color-text); }

.sheet__group + .sheet__group { margin-block-start: var(--space-5); }

.sheet__label {
  display: block;
  margin-block-end: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

/* ---- Segmented theme control ---------------------------------------------- */
.segmented {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-1);
  padding: var(--space-1);
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.segmented__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text-muted);
  background: none;
  border: 0;
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}
.segmented__btn[aria-pressed="true"] {
  color: var(--color-text);
  background: var(--color-surface);
  box-shadow: var(--shadow-xs);
}
.segmented__btn .icon { width: 1rem; height: 1rem; }

/* ---- Accent swatches ------------------------------------------------------- */
.swatches {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.swatch {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  color: var(--white);
  background: var(--swatch);
  border: 2px solid var(--color-surface);
  border-radius: var(--radius-full);
  box-shadow: 0 0 0 1px var(--color-border-strong), var(--shadow-sm);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.swatch:hover { transform: translateY(-2px); }
.swatch[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 4px var(--swatch), var(--shadow-md);
}
.swatch .icon {
  width: 1rem;
  height: 1rem;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-out);
}
.swatch[aria-pressed="true"] .icon { opacity: 1; }

/* The native picker, so "other brand colors" is not limited to the presets */
.swatch--custom {
  padding: 0;
  overflow: hidden;
  background: conic-gradient(
    from 90deg,
    #ef4444, #f59e0b, #22c55e, #06b6d4, #3b82f6, #8b5cf6, #ec4899, #ef4444
  );
}
.swatch--custom input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  padding: 0;
}

.sheet__note {
  margin-block-start: var(--space-4);
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  color: var(--color-text-subtle);
}

/* On a wide screen the sheet stops being a sheet and docks beside the frame */
@media (min-width: 64rem) {
  .sheet {
    inset-block: auto 50%;
    inset-inline: auto var(--space-8);
    width: 17rem;
    translate: 1.5rem 50%;
    opacity: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    transition: translate var(--duration-base) var(--ease-out),
                opacity var(--duration-base) var(--ease-out),
                visibility var(--duration-base) var(--ease-out);
  }
  .sheet.is-open { translate: 0 50%; opacity: 1; }
  .sheet__grip { display: none; }
  .sheet-backdrop { background: transparent; backdrop-filter: none; }
}


/* ==========================================================================
   10 — TOAST
   ========================================================================== */
/* Confirmation for the copy button — speaks, then gets out of the way */
.toast {
  position: fixed;
  inset-block-end: var(--space-6);
  inset-inline: 0;
  z-index: calc(var(--z-overlay) + 3);
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.toast__body {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text-inverse);
  background: var(--color-bg-inverse);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  translate: 0 0.75rem;
  transition: opacity var(--duration-base) var(--ease-out),
              translate var(--duration-base) var(--ease-out);
}
.toast.is-open .toast__body { opacity: 1; translate: 0 0; }
.toast .icon { width: 1rem; height: 1rem; color: var(--color-success); }


/* ==========================================================================
   11 — MOTION
   The 3D feel: things arrive from below, the avatar breathes, the glow
   drifts. All of it is enhancement — the page is complete without it.
   ========================================================================== */
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes breathe {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}

.js .rise {
  opacity: 0;
  animation: rise var(--duration-slow) var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 70ms);
}

.js .avatar { animation: breathe 6s var(--ease-in-out) 1.2s infinite; }

/* Focus is drawn in the owner's accent, same as everything else */
:where(a, button, input, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  .js .rise { opacity: 1; animation: none; }
  .js .avatar { animation: none; }
  .btn:hover,
  .link-card:hover,
  .social:hover,
  .swatch:hover,
  .tool:hover { transform: none; }
  .work:hover .icon { transform: none; }
}
