/*
 * The shared web-UI layer: the foundation every app stands on, and the component vocabulary
 * more than one app renders. Apps import this first and add their own layout on top.
 *
 * The three layers below fix the cascade once, here, for every stylesheet in the repo
 * (capabilities/styles-follow-ownership, cascade-order-guarantee):
 *
 *   foundation  — the token baseline, the reset, base elements, the focus ring
 *   vocabulary  — the ds-* components shared across apps
 *   app         — one app's own layout, and the shell's own chrome
 *
 * A later layer beats an earlier one whatever the specificity or the import order, so an app
 * can retune a component without reaching for specificity and without depending on where its
 * stylesheet happens to sit in an entrypoint's import list.
 *
 * Every stylesheet in src/ opens by declaring which layer it is in. An unlayered rule outranks
 * every layered one, so a sheet that forgets does not merely land in the wrong place — it wins
 * everything, silently.
 */
@layer foundation, vocabulary, app;

@layer foundation {
  /*
   * Every themeable surface reads its color from a CSS custom property: var(--<token>). The
   * `:root` block seeds the monochromatic baseline (kept in sync with
   * webshell/protocol/tokens.ts MONOCHROME_THEME); the shell's paintTokens() writes a brand's
   * values as inline custom properties on the document root, overriding that baseline. So first
   * paint is always styled — no unstyled flash — and a token a brand omits keeps its :root
   * baseline value rather than resolving to nothing.
   */
  :root {
    --bg: #fafafa;
    --surface: #ffffff;
    --text: #1a1a1a;
    --muted: #5c5c5c;
    --accent: #3a3a3a;
    --accent-contrast: #ffffff;
    --border: #e2e2e2;
    --danger: #cf222e;

    --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    /* Responsive contract — framework-owned, NOT brand-themeable (resolved by
       initial-ds-components/responsive-contract). Spacing is the fixed --step scale, used
       as calc(var(--step) * n); components lay out mobile-first (single column) and
       enhance to multi-column at --bp-content. CSS can't read a custom property inside a
       media query, so --bp-content documents the value the @media rules hardcode. */
    --step: 8px;
    --radius: 8px;
    --bp-content: 40rem;

    /* Touch target floor — nothing goes under this one. */
    --tap: 44px;
  }

  * {
    box-sizing: border-box;
  }

  html,
  body {
    margin: 0;
  }

  body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--sans);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
  }

  a {
    color: var(--accent);
  }

  /* Keyboard focus is part of the contract — always visible, drawn in the live accent. */
  :where(a, button, [tabindex]):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 2px;
  }
}

@layer vocabulary {
  /* ---- Type scale -------------------------------------------------------- */

  .ds-head {
    display: flex;
    flex-direction: column;
    gap: var(--step);
  }

  .ds-eyebrow {
    font-family: var(--mono);
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 0;
  }

  .ds-title {
    margin: 0;
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    font-weight: 700;
    letter-spacing: -0.02em;
  }

  .ds-lede {
    margin: 0;
    max-width: 62ch;
    color: var(--muted);
  }

  .ds-section {
    display: flex;
    flex-direction: column;
    gap: calc(var(--step) * 2);
  }

  .ds-section-title {
    margin: 0;
    font-family: var(--mono);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    padding-bottom: var(--step);
    border-bottom: 1px solid var(--border);
  }

  .ds-muted {
    color: var(--muted);
    font-size: 0.875rem;
  }

  .ds-rule {
    height: 1px;
    background: var(--border);
    border: none;
    margin: 0;
  }

  .ds-link {
    color: var(--accent);
  }

  /* ---- Buttons ----------------------------------------------------------- */

  .ds-btn {
    font: inherit;
    font-size: 0.875rem;
    padding: calc(var(--step)) calc(var(--step) * 1.75);
    min-height: var(--tap);
    border-radius: var(--radius);
    border: 1px solid var(--accent);
    cursor: pointer;
    width: fit-content;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    text-decoration: none;
  }

  .ds-btn--solid {
    background: var(--accent);
    color: var(--accent-contrast);
  }

  .ds-btn--ghost {
    background: transparent;
    color: var(--accent);
  }

  .ds-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  /* ---- List, card, form -------------------------------------------------- */
  /*
   * Each surface reads an APPLICATION token that falls back to its component-declared
   * SEMANTIC default: var(--<app>, var(--<semantic>)). A brand paints --<app> to retune
   * one surface; unset, it resolves from the palette alone. Keep these fallbacks in sync
   * with webshell/protocol/app-tokens.ts APPLICATION_TOKENS (the source of truth for the
   * mapping).
   */

  /* List — rows on a raised surface, separated by dividers. */
  .ds-list {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--list-bg, var(--surface));
    border: 1px solid var(--list-divider, var(--border));
    border-radius: var(--radius);
    overflow: hidden;
  }

  .ds-list-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--step);
    padding: calc(var(--step) * 1.5) calc(var(--step) * 2);
    border-top: 1px solid var(--list-divider, var(--border));
  }

  .ds-list-item:first-child {
    border-top: none;
  }

  .ds-list-item-title {
    color: var(--list-text, var(--text));
    font-size: 0.9375rem;
  }

  .ds-list-item-meta {
    color: var(--list-muted, var(--muted));
    font-family: var(--mono);
    font-size: 0.75rem;
    flex: none;
  }

  /* Card — a titled panel bounded by a hairline. */
  .ds-card {
    display: flex;
    flex-direction: column;
    gap: var(--step);
    padding: calc(var(--step) * 2);
    background: var(--card-bg, var(--surface));
    border: 1px solid var(--card-border, var(--border));
    border-radius: var(--radius);
  }

  .ds-card-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 650;
    color: var(--card-title, var(--text));
  }

  .ds-card-text {
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--card-text, var(--muted));
  }

  /* Form — labelled fields with bordered inputs. Mobile-first: fields stack; the field
     row can go two-up at the content breakpoint. */
  .ds-form {
    display: grid;
    grid-template-columns: 1fr;
    gap: calc(var(--step) * 1.5);
  }

  .ds-field {
    display: flex;
    flex-direction: column;
    gap: calc(var(--step) * 0.75);
  }

  .ds-field-label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--field-label, var(--text));
  }

  /* Mobile-first, and 16px is not a taste choice: iOS Safari zooms the viewport onto any field
     it focuses whose text is smaller, and never zooms back out. The 0.875rem the rest of the
     type scale uses is restored at the content breakpoint, where no browser does this. */
  .ds-input {
    font: inherit;
    font-size: max(1rem, 16px);
    padding: calc(var(--step)) calc(var(--step) * 1.25);
    background: var(--input-bg, var(--surface));
    border: 1px solid var(--input-border, var(--border));
    border-radius: var(--radius);
    color: var(--input-text, var(--text));
  }

  .ds-input::placeholder {
    color: var(--input-placeholder, var(--muted));
  }

  .ds-input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
  }

  @media (min-width: 40rem) {
    .ds-form {
      grid-template-columns: repeat(2, 1fr);
    }

    .ds-input {
      font-size: 0.875rem;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    * {
      animation: none !important;
      transition: none !important;
    }
  }
}

/*
 * This page's own layer, and nothing else. The visual world is inherited unchanged from
 * `src/frontend/ds.css` — the monochrome baseline, the 8px --step scale, hairline borders, no
 * shadow anywhere, mono reserved for data (`PAGE.md` §5). `build.ts` emits that foundation ahead
 * of this file, so the cascade the shared sheet declares — foundation, vocabulary, app — is the
 * one that applies here.
 *
 * `@layer app`, per capabilities/styles-follow-ownership: this is one surface's layout, and an unlayered
 * rule would outrank every layered one in the sheet above it.
 */
@layer app {
  .page {
    max-width: 64rem;
    margin: 0 auto;
    padding: calc(var(--step) * 5) calc(var(--step) * 3) calc(var(--step) * 12);
  }

  @media (min-width: 40rem) {
    .page {
      padding: calc(var(--step) * 12) calc(var(--step) * 6) calc(var(--step) * 16);
    }
  }

  /* ---- the offer -------------------------------------------------------- */

  .offer h1 {
    margin: 0;
    max-width: 17ch;
    font-size: clamp(2.375rem, 7vw, 4.25rem);
    font-weight: 700;
    line-height: 1.02;
    letter-spacing: -0.035em;
  }

  .lede {
    margin: calc(var(--step) * 3) 0 0;
    max-width: 68ch;
    font-size: 1.1875rem;
    color: var(--muted);
  }

  .lede strong {
    color: var(--text);
    font-weight: 600;
  }

  .name {
    margin: calc(var(--step) * 2) 0 0;
    max-width: 60ch;
    font-size: 1.0625rem;
  }

  /* The answer to the reader's fourth question, at the same weight as the offer and not tucked
     away — `PAGE.md` §1. A page in this category that hides it is lying on the first screen. */
  .fact {
    margin: calc(var(--step) * 7) 0 0;
    max-width: 24ch;
    font-size: clamp(1.375rem, 3vw, 1.75rem);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.025em;
  }

  .fact span {
    display: block;
    margin-top: calc(var(--step) * 2);
    max-width: 44ch;
    font-size: 1.0625rem;
    font-weight: 400;
    line-height: 1.6;
    letter-spacing: 0;
    color: var(--muted);
  }

  .measured {
    margin: calc(var(--step) * 4) 0 0;
    font-family: var(--mono);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    color: var(--muted);
  }

  /* ---- the ledger ------------------------------------------------------- */

  section {
    margin-top: calc(var(--step) * 8);
  }

  @media (min-width: 40rem) {
    section {
      margin-top: calc(var(--step) * 11);
    }
  }

  h2 {
    margin: 0 0 calc(var(--step) * 4);
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.02em;
  }

  h2 + .section-note {
    margin: calc(var(--step) * -3) 0 calc(var(--step) * 4);
    max-width: 68ch;
    color: var(--muted);
  }

  /* Claim left, evidence right, and on a phone claim above evidence — the reading order is the
     structure, so it survives the single column rather than being a desktop arrangement. */
  .row {
    display: grid;
    gap: calc(var(--step) * 2);
    grid-template-columns: 1fr;
    padding: calc(var(--step) * 4) 0;
    border-top: 1px solid var(--border);
  }

  .row:last-child {
    border-bottom: 1px solid var(--border);
  }

  @media (min-width: 40rem) {
    .row {
      grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
      gap: calc(var(--step) * 6);
      padding: calc(var(--step) * 5) 0;
    }
  }

  .claim h3 {
    margin: 0;
    font-size: 1.1875rem;
    font-weight: 700;
    letter-spacing: -0.015em;
  }

  .claim p {
    margin: var(--step) 0 0;
    max-width: 46ch;
  }

  .step-n {
    display: block;
    margin-bottom: calc(var(--step) * 0.5);
    font-family: var(--mono);
    font-size: 0.8125rem;
    color: var(--muted);
  }

  /* Mono earns this column because the column genuinely is measurement, not because the audience
     is technical — the distinction `PAGE.md` §5 draws, and the reason prose never wears it. */
  .backing {
    align-self: start;
  }

  .backing p {
    margin: calc(var(--step) * 1.5) 0 0;
    max-width: 44ch;
    font-family: var(--mono);
    font-size: 0.8125rem;
    line-height: 1.65;
    color: var(--muted);
    overflow-wrap: anywhere;
  }

  .backing p:first-child {
    margin-top: 0;
  }

  .backing code {
    font-family: var(--mono);
    color: var(--text);
  }

  /* Three marks for three states, typographic and bordered. No second accent colour: --danger is
     reserved for destructive states, and none of these is one (`PAGE.md` §7 anti-goals). */
  .state {
    display: inline-block;
    padding: 2px calc(var(--step) * 1.25);
    border-radius: var(--radius);
    font-family: var(--mono);
    font-size: 0.6875rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
  }

  .state--live {
    background: var(--accent);
    color: var(--accent-contrast);
  }

  .state--building {
    border: 1px solid var(--accent);
    color: var(--text);
  }

  .state--notyet {
    border: 1px dashed var(--muted);
    color: var(--muted);
  }

  .legend {
    display: grid;
    gap: calc(var(--step) * 3) calc(var(--step) * 5);
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    margin: 0 0 calc(var(--step) * 6);
    padding: 0;
    list-style: none;
  }

  .legend li {
    font-size: 0.9375rem;
    line-height: 1.5;
    color: var(--muted);
  }

  .legend .state {
    display: inline-block;
    margin-bottom: var(--step);
  }

  /* ---- the honest edge -------------------------------------------------- */

  .edge {
    margin-top: calc(var(--step) * 12);
  }

  .edge hr {
    width: 100%;
    height: 2px;
    margin: 0;
    border: 0;
    background: var(--text);
    transform-origin: left center;
    animation: draw 900ms cubic-bezier(0.16, 1, 0.3, 1) 200ms both;
  }

  @keyframes draw {
    from {
      transform: scaleX(0);
    }

    to {
      transform: scaleX(1);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .edge hr {
      animation: none;
    }
  }

  .edge p {
    margin: calc(var(--step) * 3) 0 0;
    max-width: 52ch;
    font-size: 1.375rem;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: -0.02em;
  }

  .edge p + p {
    margin-top: calc(var(--step) * 2);
    font-size: 1.0625rem;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--muted);
  }

  /* ---- what runs today -------------------------------------------------- */

  .running .row {
    padding: calc(var(--step) * 3) 0;
  }

  /* ---- close ------------------------------------------------------------ */

  .close {
    margin-top: calc(var(--step) * 12);
  }

  .close p {
    max-width: 60ch;
    font-size: 1.1875rem;
  }

  .action-note {
    display: block;
    margin-top: calc(var(--step) * 1.5);
  }

  .action-backing {
    margin: calc(var(--step) * 3) 0 0;
    max-width: 52ch;
    font-family: var(--mono);
    font-size: 0.8125rem;
    line-height: 1.65;
    color: var(--muted);
    overflow-wrap: anywhere;
  }

  footer {
    margin-top: calc(var(--step) * 12);
    padding-top: calc(var(--step) * 3);
    border-top: 1px solid var(--border);
    font-size: 0.9375rem;
    color: var(--muted);
  }
}
