/*
 * Orbyt site design system. Rules live in apps/site/docs/DESIGN_SYSTEM.md.
 *
 * Cascade layers fix precedence by intent rather than by selector weight or
 * file order: utilities beat page styles, page styles (feed.css, post.css)
 * beat components, components beat base element styles. Legacy unlayered sheets still win over all of these,
 * so a page that adopts this file must not also load skeleton.css,
 * profile.css or embed.css.
 *
 * Palette primitives (--orbyt-*) come from tokens.css, which must load first.
 */
@layer reset, tokens, base, layout, components, pages, utilities;

/* Cross-document view transitions: navigations crossfade, and the tapped
   video card morphs into the player (PostGrid sets the name on tap). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

/* ------------------------------------------------------------------ */
@layer tokens {
  :root {
    /* Semantic color. Components read only these, never the palette.
       --color-bg and --color-text are the theme inputs; a profile sets them
       from its creator colors. */
    --color-bg: var(--orbyt-black);
    --color-text: var(--orbyt-white);
    --color-accent: var(--orbyt-purple);
    --color-on-accent: var(--orbyt-white);
    --color-highlight: var(--orbyt-teal);
  }

  /* Derived color. Custom properties resolve where they are declared, so any
     element that changes the theme inputs carries [data-surface] to recompute
     these against its own values. */
  :root, [data-surface] {
    --color-text-muted: color-mix(in oklab, var(--color-text) 68%, var(--color-bg));
    --color-text-subtle: color-mix(in oklab, var(--color-text) 50%, var(--color-bg));
    --color-surface: color-mix(in oklab, var(--color-text) 6%, var(--color-bg));
    --color-surface-raised: color-mix(in oklab, var(--color-text) 11%, var(--color-bg));
    --color-border: color-mix(in oklab, var(--color-text) 16%, var(--color-bg));
    --color-focus: var(--color-text);
  }

  :root {
    /* Space: the app's scale (Theme.Spacing). Scale tokens point at their
       --app-* twin from design/tokens.json; a `site-only` value has none and
       is listed by tools/audit-site-design.mjs. */
    --space-1: var(--app-space-xxs);
    --space-2: var(--app-space-xs);
    --space-3: var(--app-space-sm);
    --space-4: var(--app-space-md);
    --space-5: var(--app-space-xl);
    --space-6: var(--app-space-xxl);
    --space-7: 3rem; /* site-only: page sections; the app's largest step is 40 */
    --space-8: 4rem; /* site-only: page sections; the app's largest step is 40 */
    --gutter: clamp(var(--space-4), 4vw, var(--space-6));

    /* Type: one family and the app's text roles (OrbytTheme TextRole):
       fineprint 12, detail 14, main 16, title 18, subHeader 20, header 28.
       Only the home headline is fluid. */
    --font-sans: 'Figtree', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
    --text-xs: var(--app-text-fineprint);
    --text-sm: var(--app-text-detail);
    --text-md: var(--app-text-main);
    --text-lg: var(--app-text-title);
    --text-xl: var(--app-text-sub-header);
    --text-2xl: var(--app-text-header);
    --text-display: clamp(2rem, 1.4rem + 2.5vw, 3rem); /* site-only: the one fluid headline */
    --leading-tight: 1.15;
    --leading-normal: 1.5;
    --weight-regular: 400;
    --weight-medium: 500;
    --weight-bold: 700;
    --weight-black: 900;

    /* Shape. */
    --radius-sm: var(--app-radius-sm);
    --radius-md: var(--app-radius-md);
    --radius-lg: var(--app-radius-panel);
    --radius-pill: 999px;
    --corner-shape: var(--orbyt-corner-shape, squircle);

    /* Size. */
    --control-size: 44px;
    --control-size-sm: 36px;
    --avatar-sm: 40px;
    --avatar-md: 48px;
    --avatar-xl: 120px;
    --content-max: 1280px;
    --prose-max: 65ch;
    --sidebar-width: clamp(17rem, 24vw, 21rem);
    --header-height: 64px;

    /* Motion. */
    --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
    --duration-fast: 120ms;
    --duration-base: 220ms;
    --duration-slow: 480ms;

    /* Elevation. */
    --shadow-raised: 0 8px 24px rgb(var(--orbyt-scrim-rgb) / 0.35);
  }

  @media (prefers-reduced-motion: reduce) {
    :root {
      --duration-fast: 0ms;
      --duration-base: 0ms;
      --duration-slow: 0ms;
    }
  }
}

/* ------------------------------------------------------------------ */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: none; text-size-adjust: none; }
  body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
  ul[role='list'], ol[role='list'] { list-style: none; padding: 0; }
  img, picture, video, svg { display: block; max-width: 100%; }
  input, button, textarea, select { font: inherit; color: inherit; }
  button { cursor: pointer; }
  [hidden] { display: none !important; }
}

/* ------------------------------------------------------------------ */
@layer base {
  html {
    color-scheme: dark;
    background: var(--color-bg);
    scrollbar-gutter: auto;
  }
  html.orbyt-doc-light { color-scheme: light; }

  body {
    min-height: 100dvh;
    font-family: var(--font-sans);
    font-size: var(--text-md);
    line-height: var(--leading-normal);
    background: var(--color-bg);
    color: var(--color-text);
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
  }

  h1, h2, h3 { line-height: var(--leading-tight); text-wrap: balance; overflow-wrap: anywhere; }
  p { text-wrap: pretty; }
  a { color: inherit; text-underline-offset: 0.2em; }

  :focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 3px;
  }
  :focus:not(:focus-visible) { outline: none; }
}

/* ------------------------------------------------------------------ */
@layer layout {
  .container {
    width: 100%;
    max-width: var(--content-max);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  .stack { display: flex; flex-direction: column; gap: var(--stack-gap, var(--space-4)); }
  .cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cluster-gap, var(--space-3)); }

  /* Identity sidebar + content. Collapses to one column below 52rem. */
  .with-sidebar {
    display: grid;
    gap: var(--space-6);
    align-items: start;
  }
  @media (min-width: 52rem) {
    .with-sidebar { grid-template-columns: var(--sidebar-width) minmax(0, 1fr); }
    .with-sidebar > .sidebar {
      position: sticky;
      top: calc(var(--header-height) + var(--space-4));
      max-height: calc(100dvh - var(--header-height) - var(--space-6));
      overflow-y: auto;
      scrollbar-width: thin;
    }
  }
}

/* ------------------------------------------------------------------ */
@layer components {
  /* Site header -------------------------------------------------------- */
  .site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: color-mix(in oklab, var(--color-bg) 78%, transparent);
    backdrop-filter: blur(16px) saturate(1.4);
    -webkit-backdrop-filter: blur(16px) saturate(1.4);
  }
  .site-header__inner {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: var(--header-height);
  }
  .site-header__brand {
    font-size: var(--text-2xl);
    font-weight: var(--weight-black);
    line-height: 1;
    letter-spacing: -0.01em;
    text-decoration: none;
    min-height: var(--control-size);
    display: inline-flex;
    align-items: center;
  }
  .site-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--space-2); }
  .site-header--overlay {
    position: absolute;
    inset-inline: 0;
    background: linear-gradient(rgb(var(--orbyt-scrim-rgb) / 0.55), transparent);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: 0;
    color: var(--orbyt-white);
  }

  /* Button --------------------------------------------------------------
     One primary per view. Secondary for alternatives, ghost for tools. */
  .button {
    --button-bg: var(--color-surface-raised);
    --button-fg: var(--color-text);
    --button-border: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--control-size);
    padding-inline: var(--space-5);
    border: 1px solid var(--button-border);
    border-radius: var(--radius-pill);
    background: var(--button-bg);
    color: var(--button-fg);
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
  }
  .button:hover { --button-bg: color-mix(in oklab, var(--color-text) 16%, var(--color-bg)); }
  .button:active { transform: scale(0.98); }
  .button:disabled, .button[aria-disabled='true'] { opacity: 0.55; cursor: default; transform: none; }
  .button svg { width: 1.25em; height: 1.25em; flex-shrink: 0; }

  .button--primary { --button-bg: var(--color-text); --button-fg: var(--color-bg); }
  .button--primary:hover { --button-bg: color-mix(in oklab, var(--color-text) 85%, var(--color-bg)); }
  .button--secondary { --button-bg: transparent; --button-border: var(--color-border); }
  .button--secondary:hover { --button-bg: var(--color-surface); --button-border: var(--color-text-subtle); }
  .button--ghost { --button-bg: transparent; padding-inline: var(--space-3); }
  .button--ghost:hover { --button-bg: var(--color-surface); }
  .button--sm { min-height: var(--control-size-sm); padding-inline: var(--space-4); font-size: var(--text-sm); }
  /* The page's one prominent call to action. */
  .button--lg { min-height: calc(var(--control-size) + var(--space-2)); padding-inline: var(--space-6); font-size: var(--text-lg); }
  .button--block { width: 100%; }
  .button--icon { padding: 0; width: var(--control-size); }
  .button--icon.button--sm { width: var(--control-size-sm); }

  /* Avatar ------------------------------------------------------------- */
  .avatar {
    --avatar-size: var(--avatar-sm);
    flex: 0 0 auto;
    width: var(--avatar-size);
    height: var(--avatar-size);
    border-radius: 50%;
    object-fit: cover;
    background: var(--color-surface-raised);
    overflow: hidden;
  }
  .avatar--md { --avatar-size: var(--avatar-md); }
  .avatar--xl { --avatar-size: var(--avatar-xl); }
  @media (max-width: 51.99rem) { .avatar--xl { --avatar-size: 96px; } }
  /* The app's portrait ring: a 2px line in the text color, flush to the image. */
  .avatar--ring { border: 2px solid var(--color-text); }

  /* Stats: value over unit, as the app's Community counts. ---------------- */
  /* Value and unit sit tight, as the app's statistic (spacing 0, unit pulled
     up a hairline); the gap is between stats, not inside one. */
  .stat-list { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); padding: 0; margin: 0; }
  .stat-list > div { display: flex; flex-direction: column-reverse; }
  .stat-list dt { color: var(--color-text-muted); font-size: var(--text-md); line-height: 1.15; }
  .stat-list dd { font-size: var(--text-lg); font-weight: var(--weight-bold); line-height: 1.15; font-variant-numeric: tabular-nums; }

  /* Identity: profile and Community headers. Plain text on the page's own
     color, no card, laid out like ProfileView.profileHeader. ------------ */
  /* ProfileView's rhythm grows down the block: portrait to name 12, name to
     handle 2, handle to bio 20, bio to counts 20. */
  .identity { display: flex; flex-direction: column; gap: var(--space-5); }
  .identity__portrait { margin-block-end: calc(var(--space-3) - var(--space-5)); }
  .identity__names { display: grid; gap: 2px; }
  .identity__names p { line-height: 1.3; }
  .identity__name { font-size: var(--text-2xl); font-weight: var(--weight-black); letter-spacing: -0.01em; }
  .identity__name--handle { overflow-wrap: normal; }
  /* The beta mark sits on the name, as the app's BetaBadge, not in a pill. */
  .identity__badge { display: inline-block; margin-inline-start: var(--space-1); vertical-align: 0.05em; }
  .identity__badge svg { width: 0.6em; height: 0.6em; }
  .identity__handle { font-size: var(--text-lg); font-weight: var(--weight-medium); overflow-wrap: anywhere; }
  .identity__bio { white-space: pre-wrap; overflow-wrap: anywhere; max-width: var(--prose-max); font-weight: var(--weight-medium); }
  .identity__bio a { text-decoration: underline; }

  /* Section heading ---------------------------------------------------- */
  .section-heading {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    margin-block-end: var(--space-4);
  }
  .section-heading h2 { font-size: var(--text-xl); font-weight: var(--weight-black); }

  /* Notice: inline empty, error and retry states ----------------------- */
  .notice {
    display: grid;
    justify-items: center;
    gap: var(--space-3);
    padding: var(--space-7) var(--space-4);
    color: var(--color-text-muted);
    text-align: center;
  }
  /* Toby sits close above his message, as in the app's empty states. */
  .notice--toby { gap: var(--space-2); }
  .notice--inline { justify-items: start; text-align: start; padding: var(--space-2) 0; }

  /* Dead air: a whole page with nothing to show (404, unavailable) ----
     Toby sits on the heading as the app's empty states do, the line under
     it reads as part of the same block, and the actions follow a step
     apart, all held a little above the middle of the page. */
  .dead-air {
    flex: 1;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: var(--space-5);
    padding-block: var(--space-7) var(--space-8);
    text-align: center;
  }
  .dead-air__text { display: grid; justify-items: center; gap: var(--space-2); }
  /* His box keeps room under his feet; this sets him down on the heading. */
  .dead-air__text .toby { margin-block-end: calc(var(--space-1) - var(--space-2)); }
  .dead-air__text h1 { margin: 0; font-size: var(--text-2xl); font-weight: var(--weight-black); line-height: var(--leading-tight); }
  .dead-air__text p { margin: 0; max-width: 32ch; color: color-mix(in oklab, var(--color-text) 78%, var(--color-bg)); font-size: var(--text-lg); font-weight: var(--weight-medium); line-height: var(--leading-normal); }
  .dead-air__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); }
  /* A matched pair: the same width, so neither reads as the odd one out. */
  .dead-air__actions .button { min-inline-size: calc(var(--control-size) * 3); }

  /* Community card ----------------------------------------------------- */
  .community-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 10.5rem), 1fr));
    gap: var(--space-5) var(--space-4);
    padding: 0;
    margin: 0;
    list-style: none;
  }
  .community-card { display: grid; gap: var(--space-3); align-content: start; text-decoration: none; color: inherit; }
  .community-card__art {
    aspect-ratio: 1;
    border-radius: var(--radius-lg);
    corner-shape: var(--corner-shape);
    overflow: hidden;
    background: var(--community-accent, var(--color-accent));
  }
  /* The <picture> wrapper must fill the square too, or the image sizes to its
     own aspect ratio and leaves a band of accent above or below it. */
  .community-card__art :is(picture, img) { width: 100%; height: 100%; object-fit: cover; }
  .community-card__art img { transition: opacity var(--duration-slow) var(--ease-out), scale var(--duration-base) var(--ease-out); }
  .community-card__art[data-pending] img { opacity: 0; }
  @media (hover: hover) { .community-card:hover .community-card__art img { scale: 1.04; } }
  /* Name and description read as one unit, tight under the art. */
  .community-card__text { display: grid; gap: var(--space-1); }
  .community-card__name { font-size: var(--text-md); font-weight: var(--weight-bold); line-height: var(--leading-tight); overflow-wrap: anywhere; }
  .community-card__description {
    color: var(--color-text-muted);
    font-size: var(--text-sm);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
  }
  .community-card:focus-visible { outline: none; }
  .community-card:focus-visible .community-card__art { outline: 2px solid var(--color-focus); outline-offset: 3px; }

  /* Video grid: the app's VideoThumbnailGrid. Three columns, a 2px gutter,
     9:14 cards, no captions over the art. -------------------------------- */
  .video-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2px;
    padding: 0;
    margin: 0;
    list-style: none;
  }
  @media (min-width: 64rem) { .video-grid { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); } }

  .video-card__link {
    position: relative;
    display: block;
    aspect-ratio: 9 / 14;
    overflow: hidden;
    background: var(--color-surface);
    isolation: isolate;
  }
  .video-card__thumb {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: var(--video-fit, cover);
    z-index: 1;
    transition: opacity var(--duration-fast) var(--ease-out);
  }
  .video-card__link:hover .video-card__thumb { opacity: 0.85; }
  .video-card .video-ambient-backdrop { position: absolute; inset: 0; z-index: 0; }
  .video-card__link:focus-visible { outline-offset: -2px; }

}

/* ------------------------------------------------------------------ */
@layer utilities {
  .visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .muted { color: var(--color-text-muted); }
}

/* Rich text (parseRichText output) and media backdrops, shared by every page
   that renders captions or bios. */
@layer components {
  .link { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; overflow-wrap: anywhere; }
  .mention { color: inherit; text-decoration: none; font-weight: var(--weight-bold); }
  .link:hover, .mention:hover { opacity: 0.8; }

  .video-ambient-backdrop {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
    background: var(--orbyt-neutral-950);
    overflow: hidden;
  }
  .video-ambient-backdrop img { width: 100%; height: 100%; object-fit: cover; filter: blur(30px) brightness(0.6); transform: scale(1.1); }
}
