/* ─────────────────────────────────────────────────────────────
 * linkhub — shell styles
 *
 * Light / "plywood" aesthetic. Warm wood-tone background, cream cards,
 * navy type, orange accent for conversion. Mobile-first. Inter webfont.
 *
 * Every color is a CSS variable so a profile's CSV row can override it.
 * shell.js writes the overrides onto :root at mount.
 *
 * Design principles:
 *   1. Typography hierarchy: 14 / 15 / 20 / 28, weights 400/500/700/800.
 *   2. The lead magnet is visually ~2x the weight of any other block —
 *      breathing glow + accent border + larger padding.
 *   3. Default link shape is the linkin.bio "bubble" — full-width row with
 *      a thumbnail on the left and title/arrow on the right. Cleaner than
 *      an IG-grid for text-heavy link lists. Wide + square still supported.
 *   4. Featured type promotes important links (website, YouTube) to
 *      prominent pill buttons right under the bio.
 *   5. Motion is purposeful: stagger reveals, breathing CTA, subtle
 *      ambient gradient drift. Everything honors prefers-reduced-motion.
 * ───────────────────────────────────────────────────────────── */

/* ── Ambient background ──────────────────────────────────────── */
/* Slow drifting radial gradient in a darker plywood tone — gives the
   flat warm bg a sense of depth without reading as "pattern". Lives
   behind everything and never intercepts taps. */

.bg-ambient{
  position:fixed;inset:-20vh -10vw;z-index:-1;pointer-events:none;
  background:
    radial-gradient(60% 40% at 20% 0%,   color-mix(in srgb, var(--bg-2) 60%, transparent) 0%, transparent 60%),
    radial-gradient(70% 50% at 100% 30%, color-mix(in srgb, var(--bg-2) 45%, transparent) 0%, transparent 65%),
    radial-gradient(50% 40% at 50% 100%, color-mix(in srgb, var(--bg-2) 50%, transparent) 0%, transparent 65%);
  filter:blur(40px);
  animation:drift 22s ease-in-out infinite alternate;
}
@keyframes drift{
  0%  {transform:translate3d(0,0,0) scale(1)}
  100%{transform:translate3d(-4%, 2%, 0) scale(1.08)}
}

/* ── Hero ────────────────────────────────────────────────────── */

.hero{
  display:flex;flex-direction:column;align-items:center;gap:14px;
  text-align:center;margin-bottom:22px;
  animation:riseIn .65s var(--ease-spring) both;
}
.hero__avatar-wrap{
  position:relative;
  /* Soft accent glow behind the avatar — uses the accent variable so
     reskinning a profile touches a single variable. */
  filter:drop-shadow(0 12px 36px color-mix(in srgb, var(--accent) 28%, transparent));
}
.hero__avatar{
  width:112px;height:112px;border-radius:50%;
  background:var(--card);object-fit:cover;aspect-ratio:1/1;
  /* Double ring: tight bg-color ring then accent outer ring. Keeps the
     avatar visually separated from the plywood even with a similar-toned
     profile photo. */
  box-shadow:0 0 0 3px var(--bg), 0 0 0 5px var(--accent);
  display:block;
}
.hero__name{
  margin:6px 0 0;
  font-size:34px;font-weight:800;letter-spacing:-0.022em;
  line-height:1.1;color:var(--fg);
}
.hero__bio{
  margin:0;color:var(--muted);max-width:32ch;
  font-size:17px;line-height:1.5;font-weight:500;
}

/* Live-pulse handle under the name, e.g. "@stern_math" */
.hero__handle{
  display:inline-flex;align-items:center;gap:6px;
  font-size:15px;color:var(--muted);letter-spacing:.01em;
  margin-top:-2px;font-weight:500;
}
.hero__handle::before{
  content:"";display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 10px var(--accent);
  animation:pulseDot 2.4s ease-in-out infinite;
}
@keyframes pulseDot{
  0%,100%{opacity:.7;transform:scale(1)}
  50%    {opacity:1;transform:scale(1.15)}
}

/* ── Featured top-priority pills ────────────────────────────── */
/* For the website + YouTube buttons the user wants prominent at the top.
   Full-width, icon left, label center-left, arrow right. No thumbnails —
   icon does the job. Heavier visual weight than the old tiny social icons. */

.featured{
  display:flex;flex-direction:column;gap:12px;
  margin:4px 0 20px;
  animation:riseIn .65s var(--ease-spring) both;
  animation-delay:.06s;
}
.featured__item{
  display:flex;align-items:center;gap:14px;
  padding:14px 18px;
  background:var(--card);color:var(--fg);
  border:1px solid var(--border);
  border-radius:999px;
  text-decoration:none;
  font-weight:600;font-size:17px;letter-spacing:-0.003em;
  -webkit-tap-highlight-color:transparent;
  transition:transform .18s var(--ease-out), background .2s ease, border-color .2s ease;
  box-shadow:0 2px 0 rgba(42,56,144,.04);
}
.featured__item:active{
  transform:scale(.98);
  background:var(--card-2);
  border-color:color-mix(in srgb,var(--accent) 45%,transparent);
}
.featured__item svg{color:var(--fg);flex:none}
.featured__item__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.featured__item__arrow{color:var(--fg);font-size:26px;line-height:1;flex:none;opacity:.55}

/* ── Socials strip (optional, bottom-of-page tiny icons) ───── */
/* Still supported for profiles that want a social row in addition to or
   instead of featured pills. Rendered smaller and less-dominant than
   featured. Sternmath's profile uses featured instead and has no socials. */

.socials{
  display:flex;flex-wrap:wrap;justify-content:center;gap:10px;
  margin-top:2px;margin-bottom:4px;
}
.socials__item{
  width:42px;height:42px;border-radius:50%;
  background:var(--card);color:var(--fg);
  display:inline-flex;align-items:center;justify-content:center;
  text-decoration:none;
  border:1px solid var(--border);
  transition:transform .2s var(--ease-out), background .2s ease, color .2s ease;
  -webkit-tap-highlight-color:transparent;
}
.socials__item:active{transform:scale(.9);background:var(--accent);color:var(--accent-ink);border-color:transparent}

/* ── Lead-magnet card (Klaviyo top flow) ────────────────────── */
/* Primary conversion surface. ~2x the visual weight of anything else.
   Cream gradient card, subtle accent border, breathing CTA glow. */

.lead{
  position:relative;
  background:linear-gradient(135deg, #FEFBEE 0%, var(--card) 100%);
  border-radius:var(--radius-lg);
  padding:22px 20px;
  margin:4px 0 26px;
  border:1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  overflow:hidden;
  animation:riseIn .65s var(--ease-spring) both;
  animation-delay:.12s;
  box-shadow:
    0 8px 28px -14px rgba(42,56,144,.35),
    0 1px 0 rgba(255,255,255,.5) inset;
}
/* Soft accent halo in the top-right — signals importance without shouting. */
.lead::before{
  content:"";position:absolute;inset:-40% -20% auto auto;
  width:60%;aspect-ratio:1/1;border-radius:50%;
  background:radial-gradient(closest-side, color-mix(in srgb, var(--accent) 35%, transparent), transparent 70%);
  pointer-events:none;
  filter:blur(30px);
  animation:leadGlow 4.5s ease-in-out infinite;
}
@keyframes leadGlow{
  0%,100%{opacity:.7;transform:translate(0,0) scale(1)}
  50%    {opacity:1;transform:translate(-4%,4%) scale(1.08)}
}

.lead__eyebrow{
  display:inline-flex;align-items:center;gap:6px;
  margin:0 0 8px;
  font-size:14px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--fg);  /* black per "text should all be black or white" */
}
/* Decorative dot keeps the brand accent — it's a mark, not text. */
.lead__eyebrow::before{
  content:"";display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 8px var(--accent);
}

.lead__title{
  margin:0 0 6px;
  font-size:24px;font-weight:700;letter-spacing:-0.015em;line-height:1.25;
  color:var(--fg);
}
.lead__desc{
  margin:0 0 16px;color:var(--muted);
  font-size:16px;line-height:1.5;font-weight:500;
}
.lead__cta{
  position:relative;
  display:block;width:100%;
  padding:16px 20px;border:none;border-radius:999px;
  background:var(--accent);color:var(--accent-ink);
  font:inherit;font-weight:700;font-size:17px;letter-spacing:-0.005em;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .18s var(--ease-out), filter .25s ease;
  /* Breathing glow — rhythmic accent halo pulls the eye without shouting. */
  box-shadow:
    0 10px 28px -6px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent);
  animation:breathe 3.2s ease-in-out infinite;
}
.lead__cta:active{transform:scale(.97);filter:brightness(.95);animation-play-state:paused}
@keyframes breathe{
  0%,100%{box-shadow:0 10px 28px -6px color-mix(in srgb, var(--accent) 55%, transparent), 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent)}
  50%    {box-shadow:0 14px 36px -6px color-mix(in srgb, var(--accent) 70%, transparent), 0 0 0 8px color-mix(in srgb, var(--accent) 18%, transparent)}
}

/* Form shown in place of the CTA after first tap */
.lead-form{display:flex;flex-direction:column;gap:12px;margin-top:2px;position:relative;z-index:1}
.lead-form__field{display:flex;flex-direction:column;gap:6px;font-size:14px;font-weight:600;color:var(--muted);letter-spacing:.05em;text-transform:uppercase}
.lead-form__field input{
  font:inherit;font-size:18px;font-weight:500;color:var(--fg);letter-spacing:normal;text-transform:none;
  padding:13px 16px;border-radius:14px;
  background:rgba(255,255,255,.6);
  border:1px solid rgba(42,56,144,.14);
  outline:none;
  transition:border-color .18s ease, background .18s ease, box-shadow .18s ease;
}
.lead-form__field input:focus{
  border-color:var(--accent);
  background:#fff;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.lead-form__honey{
  position:absolute!important;left:-9999px;top:-9999px;
  width:1px;height:1px;overflow:hidden;opacity:0;pointer-events:none;
}
.lead-form__check{display:flex;align-items:center;gap:10px;font-size:16px;color:var(--muted);font-weight:500}
.lead-form__check input{width:18px;height:18px;accent-color:var(--accent)}
.lead-form__submit{
  margin-top:4px;padding:14px 18px;border:none;border-radius:999px;
  background:var(--accent);color:var(--accent-ink);
  font:inherit;font-weight:700;font-size:17px;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .18s var(--ease-out), filter .2s ease;
  box-shadow:0 6px 18px -6px color-mix(in srgb, var(--accent) 60%, transparent);
}
.lead-form__submit:active{transform:scale(.97);filter:brightness(.95)}
.lead-form__submit[disabled]{opacity:.6;cursor:progress}
.lead-form__status{margin:0;font-size:15px;min-height:1.4em;font-weight:500}
.lead-form__status[data-kind="error"]{color:#b3001e}
.lead-form__status[data-kind="ok"]{color:#0b7a3d}

/* ── Klaviyo embed overrides ─────────────────────────────────
 * The embedded Klaviyo form brings its own CSS from the form builder, so
 * rather than fight with it everywhere we do targeted surgery:
 *   1. Strip top margin/padding so there's no gap between our description
 *      and the first form element. Klaviyo's own form tag ships with
 *      padding-top:10px + margin-top:8px — cumulatively that leaves a ~26px
 *      dead zone under our "0–10." copy. Zeroing both here closes it up.
 *   2. Transparent backgrounds so the cream card shows through.
 *   3. Restyle the submit button to match our .lead__cta exactly (same
 *      navy fill, pill shape, Inter 700, letter-spacing, shadow, tap-scale).
 *
 * `!important` is necessary because Klaviyo inlines styles at form-render
 * time. If Klaviyo renames their class roots (they do every few months),
 * the button override may drift — easiest repair is re-running the DOM
 * inspection and updating the selectors below. Visuals that don't match
 * can always be fixed inside Klaviyo's form builder too.
 */
[class^="klaviyo-form-"],
[class*=" klaviyo-form-"]{
  width:100%;
  max-width:100%;
  margin:0;
}
.lead [class^="klaviyo-form-"],
.lead [class*=" klaviyo-form-"]{
  margin-top:0!important;
}
/* Kill the padding/margin Klaviyo puts on the form element itself. */
.lead [class^="klaviyo-form-"] form,
.lead [class*=" klaviyo-form-"] form,
.lead [data-testid="form-row"],
.lead [data-testid="form-component"]{
  background:transparent!important;
  box-shadow:none!important;
  margin-top:0!important;
  padding-top:0!important;
}
/* Some Klaviyo templates wrap each row in an extra div with its own
   padding-top:10px — catch the first-of-type row and collapse it. */
.lead [class^="klaviyo-form-"] form > div:first-child,
.lead [class^="klaviyo-form-"] form > div:first-child > div:first-child{
  padding-top:0!important;
  margin-top:0!important;
}

/* Submit button — minimal overrides. Only the brand-critical bits (color
   + font) are forced; height, padding, corner radius, and shape all come
   from Klaviyo's form builder. Previous rev forced pill-shape + 16px
   vertical padding + glow shadow on top of Klaviyo's existing styling,
   which stacked to a too-tall button. If you want the button pill-shaped
   again, set border-radius to 999px inside Klaviyo's form editor rather
   than here — keeps one source of truth. */
.lead [class^="klaviyo-form-"] button[type="submit"],
.lead [class^="klaviyo-form-"] form button{
  background:var(--accent)!important;
  color:var(--accent-ink)!important;
  font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif!important;
  font-weight:700!important;
  letter-spacing:-0.005em!important;
  text-transform:none!important;
  width:100%!important;
  transition:transform .18s var(--ease-out), filter .25s ease!important;
  cursor:pointer!important;
}
.lead [class^="klaviyo-form-"] button[type="submit"]:active,
.lead [class^="klaviyo-form-"] form button:active{
  transform:scale(.97)!important;
  filter:brightness(.95)!important;
}

/* Celebratory success card shown after the form successfully submits */
.lead-success{
  text-align:center;padding:10px 4px 4px;
  animation:riseIn .5s var(--ease-spring) both;
}
.lead-success__emoji{font-size:42px;display:block;margin-bottom:4px}
.lead-success__title{margin:0 0 4px;font-size:22px;font-weight:700;color:var(--fg)}
.lead-success__desc{margin:0;color:var(--muted);font-size:16px;font-weight:500}

/* ── Link tiles ──────────────────────────────────────────────── */
/* Four shapes, picked from the CSV `extra=shape=<name>`:
 *   bubble (default) — full-width row, thumbnail left + title/arrow right (linkin.bio style)
 *   wide             — cinematic 16:9 full-width banner with image bg
 *   square           — 2-up grid of square image tiles (IG-feed feel)
 *   pill             — plain text row with arrow, no image (secondary links)
 * The grid switches to single-column whenever `bubble`/`wide`/`pill` tiles
 * appear — we only hit the 2-col IG-grid layout when `square` is in play.
 * shell.js just sets `.tile` + modifier classes; CSS handles the rest. */

.links{
  /* minmax(0, 1fr) instead of bare 1fr: the default `1fr` resolves to
     minmax(auto, 1fr), and `auto` means the column expands to fit the
     largest min-content child. With `white-space:nowrap` on the tile's
     title/description, that min-content could be the full untruncated
     text — which blew the grid column out past the viewport. Explicit
     `0` floor keeps the column constrained to the container width. */
  display:grid;grid-template-columns:minmax(0, 1fr);gap:14px;
}

/* Default (.tile with no modifier) is now the bubble variant because it's
   what a modern text-heavy bio page wants. Override with shape=square to
   get the old IG-grid tile. */
.tile{
  position:relative;
  display:flex;align-items:center;gap:14px;
  /* Default padding is symmetric (14px each side) — used when there's no
     thumbnail. The :has() rule below tightens the left padding back to
     10px when a .tile__thumb is present, because the thumb visually owns
     that gutter. Keeps bubbles with + without images looking balanced. */
  min-height:72px;padding:10px 14px;
  background:var(--card);
  border:1px solid var(--border);
  border-radius:var(--radius);
  text-decoration:none;color:var(--fg);
  animation:riseIn .6s var(--ease-spring) both;
  animation-delay:calc(.18s + var(--i,0) * .05s);
  transition:transform .22s var(--ease-out), background .2s ease, border-color .2s ease;
  -webkit-tap-highlight-color:transparent;
  box-shadow:0 1px 0 rgba(0,0,0,.04);
}
.tile:not(.tile--wide):not(.tile--square):not(.tile--pill):has(.tile__thumb){
  padding-left:10px;
}
.tile:active{
  transform:scale(.985);
  background:var(--card-2);
  border-color:color-mix(in srgb, var(--accent) 40%, transparent);
}
.tile__thumb{
  width:56px;height:56px;border-radius:16px;
  object-fit:cover;flex:none;background:var(--card-2);
}
/* (Placeholder letter-tile was previously rendered when a bubble had no
   image. Removed — the user preferred no thumbnail at all over a
   profile-avatar-looking placeholder. If the CSV later supplies real image
   filenames, the <img> renders as the thumbnail; if the file 404s, the
   <img> is removed entirely and the bubble reflows text-only.) */
.tile__body{
  flex:1;min-width:0;
  display:flex;flex-direction:column;justify-content:center;gap:2px;
}
.tile__title{
  margin:0;font-size:17px;font-weight:700;letter-spacing:-0.005em;line-height:1.25;
  color:var(--fg);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.tile__desc{
  margin:0;font-size:15px;color:var(--muted);font-weight:500;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.tile__arrow{
  color:var(--fg);font-size:26px;line-height:1;flex:none;
  margin-right:4px;opacity:.55;
  transition:transform .25s var(--ease-out), opacity .2s ease;
}
.tile:active .tile__arrow{opacity:1}
.tile:active .tile__arrow{transform:translateX(3px)}

/* ── Wide (cinematic banner) variant ────────────────────────── */
/* 16:4.5 is intentionally half the height of 16:9 — the user wanted the
   Why Stern banner to feel more like a slim hero strip than a full image.
   Works out to ~100px tall on a 375-wide mobile viewport. */
.tile--wide{
  display:block;padding:0;overflow:hidden;
  aspect-ratio:16/4.5;min-height:0;
  position:relative;color:#fff;
}
.tile--wide .tile__img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;z-index:0;
  transition:transform .6s var(--ease-out);
}
.tile--wide:hover .tile__img{transform:scale(1.06)}
.tile--wide::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,0) 30%, rgba(0,0,0,.65) 100%);
}
.tile--wide .tile__body{
  position:absolute;z-index:2;left:0;right:0;bottom:0;
  padding:16px 18px;
  gap:2px;
}
.tile--wide .tile__title{
  font-size:22px;color:#fff;
  text-shadow:0 2px 14px rgba(0,0,0,.4);
  white-space:normal;
}
.tile--wide .tile__desc{
  color:rgba(255,255,255,.9);
  text-shadow:0 2px 14px rgba(0,0,0,.4);
  white-space:normal;
}
.tile--wide .tile__arrow{display:none}

/* ── Square (IG-grid) variant ───────────────────────────────── */
/* When used, shell.js upgrades the grid to 2-col. Kept for profiles that
   actually want a feed-style tile grid. */
.tile--square{
  display:block;padding:0;overflow:hidden;
  aspect-ratio:1/1;min-height:0;
  position:relative;color:#fff;
}
.tile--square .tile__img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  transition:transform .6s var(--ease-out);
}
.tile--square:hover .tile__img{transform:scale(1.08)}
.tile--square::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,0) 40%, rgba(0,0,0,.6) 100%);
}
.tile--square .tile__body{
  position:absolute;z-index:2;left:0;right:0;bottom:0;
  padding:12px;
}
.tile--square .tile__title{
  font-size:17px;color:#fff;
  text-shadow:0 2px 14px rgba(0,0,0,.4);
  white-space:normal;
}
.tile--square .tile__desc{
  color:rgba(255,255,255,.85);
  text-shadow:0 2px 14px rgba(0,0,0,.4);
  white-space:normal;
}
.tile--square .tile__arrow{display:none}

/* Pill — no image, just a text row. Lighter than bubble. */
.tile--pill{
  min-height:52px;padding:12px 18px;
  justify-content:space-between;
}
.tile--pill .tile__thumb{display:none}
.tile--pill .tile__body{padding-left:2px}
.tile--pill .tile__title{font-weight:600;font-size:17px}

/* When the grid has any square tiles, switch it to the 2-up IG layout.
   `has-square` is set by shell.js based on what's in the CSV. */
.links.has-square{grid-template-columns:1fr 1fr;gap:14px}
.links.has-square .tile:not(.tile--square):not(.tile--wide){grid-column:1/-1}

/* Badges */
.tile__badge{
  background:var(--accent);color:var(--accent-ink);
  font-size:12px;font-weight:700;letter-spacing:.08em;
  padding:4px 8px;border-radius:999px;text-transform:uppercase;
  flex:none;margin-right:4px;
}
.tile--wide .tile__badge,
.tile--square .tile__badge{
  position:absolute;top:10px;left:10px;z-index:2;margin:0;
}
.tile__updated{
  background:rgba(42,56,144,.1);color:var(--fg);
  font-size:12px;font-weight:600;
  padding:4px 8px;border-radius:999px;
  flex:none;
}
.tile--wide .tile__updated,
.tile--square .tile__updated{
  position:absolute;top:10px;right:10px;z-index:2;
  background:rgba(0,0,0,.55);color:#fff;
  backdrop-filter:blur(8px);
}

/* Section header */
.section-title{
  grid-column:1/-1;margin:18px 0 2px;
  font-size:13px;text-transform:uppercase;letter-spacing:.14em;color:var(--muted);
  font-weight:700;
}

/* Plain horizontal-rule separator — used when a CSV `section` row has an
   empty title. Gives a subtle break between groups of links without the
   visual weight of a labeled heading. */
.section-divider{
  grid-column:1/-1;margin:16px 0 6px;
  height:1px;border:none;
  background:linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--fg) 22%, transparent) 20%,
    color-mix(in srgb, var(--fg) 22%, transparent) 80%,
    transparent 100%
  );
}

/* ── Sticky conversion CTA ────────────────────────────────────── */
/* Appears after the user scrolls past the lead-magnet card. Tap reopens
   the form (scrolls back and focuses the first field). Glass-blurred pill
   pinned to the safe-area bottom. */

/* Frosted-glass pill. The magic is the combo of a low-opacity bg + a
   strong backdrop-filter blur + a bright inner highlight. Reading "through"
   the bar you can see the plywood and cream card colors get blurred into
   a soft haze — looks like actual glass on iOS / Android. */
.sticky-cta{
  position:fixed;left:12px;right:12px;
  bottom:calc(12px + var(--safe-bot));
  max-width:536px;margin:0 auto;
  display:flex;align-items:center;gap:12px;
  padding:10px 10px 10px 20px;
  /* Low-opacity base lets backdrop-filter do the heavy lifting */
  background:rgba(255,255,255,.32);
  backdrop-filter:blur(24px) saturate(180%);
  -webkit-backdrop-filter:blur(24px) saturate(180%);
  border:1px solid rgba(255,255,255,.5);
  border-radius:999px;
  box-shadow:
    0 20px 60px -18px rgba(0,0,0,.25),
    0 1px 0 rgba(255,255,255,.7) inset,  /* top highlight, catches the eye like a glass bevel */
    0 -1px 0 rgba(0,0,0,.04) inset;       /* subtle bottom shadow for depth */
  z-index:10;
  transform:translateY(140%);
  opacity:0;
  pointer-events:none;
  transition:transform .45s var(--ease-spring), opacity .25s ease;
}
.sticky-cta[data-visible="true"]{
  transform:translateY(0);
  opacity:1;
  pointer-events:auto;
}
.sticky-cta__label{
  flex:1;min-width:0;
  font-size:16px;font-weight:600;color:var(--fg);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.sticky-cta__btn{
  flex:none;
  padding:10px 18px;border:none;border-radius:999px;
  background:var(--accent);color:var(--accent-ink);
  font:inherit;font-weight:700;font-size:16px;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .15s var(--ease-out);
  box-shadow:0 4px 12px -4px color-mix(in srgb, var(--accent) 60%, transparent);
}
.sticky-cta__btn:active{transform:scale(.95)}

/* ── Empty / error state ────────────────────────────────────── */

.error-state{
  padding:48px 20px;text-align:center;color:var(--muted);
}
.error-state h1{font-size:26px;margin:0 0 8px;color:var(--fg);font-weight:700;letter-spacing:-0.01em}

/* ── Motion ──────────────────────────────────────────────────── */

@keyframes riseIn{
  from{opacity:0;transform:translateY(16px)}
  to  {opacity:1;transform:translateY(0)}
}

/* Kill all motion if the user asks for reduced motion. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .bg-ambient{animation:none!important}
}

/* Small phones */
@media (max-width:360px){
  body{padding-left:14px;padding-right:14px}
  .links{gap:12px}
  .links.has-square{gap:12px}
  .hero__name{font-size:30px}
  .featured__item{padding:12px 16px}
}
