/* ═══════════════════════════════════════════════════════════════════════
   Phaeacia — design tokens
   Version 1.0 · 2026-08-08

   THEMING CONTRACT (do not break this, it is the source of most theme bugs):
   the complete light palette is declared once on bare :root. The two dark
   blocks redefine token VALUES only. No colour is ever declared for the
   first time inside a media query or a [data-theme] block, so a page that
   opts out of dark mode still has every token defined.

   Set the initial theme before first paint with the snippet in DESIGN-GUIDE.md,
   or the page flashes light before switching.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── ground and ink ────────────────────────────────────────────────── */
  --ph-paper:        #F7F3EC;   /* page ground, warm bone                */
  --ph-paper-deep:   #EDE6DA;   /* cards, wells, secondary surfaces      */
  --ph-card:         #FBF9F4;   /* raised surface on paper               */
  --ph-line:         #DCD4C6;   /* hairlines, borders, dividers          */
  --ph-line-soft:    #E9E3D8;   /* the quieter rule                      */
  --ph-ink:          #10171A;   /* body text, headlines                  */
  --ph-mute:         #5B6669;   /* secondary text  (5.3:1 on paper)      */

  /* ── the sea ───────────────────────────────────────────────────────── */
  --ph-deep:         #0C3945;   /* PRIMARY. mark, links, buttons (11.3:1)*/
  --ph-tide:         #175567;   /* hover, large fills                    */
  --ph-shoal:        #58A0AE;   /* light sea. dark grounds only          */
  --ph-shoal-soft:   #DDECEF;   /* tinted surface, light mode            */

  /* ── the one warm accent ───────────────────────────────────────────── */
  --ph-brass:        #A8763A;   /* eyebrows, numerals, rare emphasis     */
  --ph-brass-soft:   #F1E7D8;

  /* ── state ─────────────────────────────────────────────────────────── */
  --ph-good:         #2F6B52;
  --ph-warn:         #A8763A;
  --ph-bad:          #97402C;

  /* ── Agent Passport, the only product-level colours that exist ─────── */
  --pp-granted:      #2F6B52;   /* a capability that installs             */
  --pp-refused:      #97402C;   /* declared only, and the losses table    */

  /* ── elevation ─────────────────────────────────────────────────────── */
  --ph-shadow:       0 1px 1px rgb(16 23 26 / .04), 0 16px 38px -22px rgb(16 23 26 / .32);
  --ph-shadow-soft:  0 1px 2px rgb(16 23 26 / .05);

  /* ── type ──────────────────────────────────────────────────────────── */
  --ph-sans: "Schibsted Grotesk", ui-sans-serif, system-ui, -apple-system,
             "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --ph-mono: "DM Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
             Consolas, "Liberation Mono", monospace;

  /* type scale, 1.25 from 17px body */
  --ph-t-display: clamp(2.6rem, 1.6rem + 3.4vw, 4.25rem);  /* 42 → 68px  */
  --ph-t-h1:      clamp(2.0rem, 1.4rem + 2.1vw, 3.0rem);
  --ph-t-h2:      1.625rem;
  --ph-t-h3:      1.25rem;
  --ph-t-body:    1.0625rem;    /* 17px                                  */
  --ph-t-small:   0.9375rem;
  --ph-t-micro:   0.6875rem;    /* mono eyebrows and labels              */

  --ph-lh-display: 1.04;
  --ph-lh-head:    1.15;
  --ph-lh-body:    1.62;

  --ph-tr-display: -0.034em;    /* display tracks tight                  */
  --ph-tr-head:    -0.02em;
  --ph-tr-body:     0em;
  --ph-tr-micro:    0.12em;     /* mono labels track wide, uppercase     */

  /* ── space, 4px base ───────────────────────────────────────────────── */
  --ph-1: 4px;  --ph-2: 8px;  --ph-3: 12px; --ph-4: 16px;
  --ph-5: 24px; --ph-6: 32px; --ph-7: 48px; --ph-8: 72px; --ph-9: 112px;

  /* ── rhythm: which STEP of that scale a structural role sits on ──────
     DESIGN-GUIDE section 6.1. The scale itself never changes with the
     viewport; what changes is the step each role takes. A 1440 page and a
     390 page were being spaced from the same top of the scale, which is
     how 112px of air ended up between two paragraphs on a phone and read
     as a rendering failure rather than as generosity.
     Below 640 every structural role steps down exactly one notch. */
  --ph-band:  var(--ph-9);   /* 112 : a section's own vertical air         */
  --ph-stack: var(--ph-8);   /* 72  : between major blocks inside one      */
  --ph-block: var(--ph-7);   /* 48  : heading group to its content         */
  --ph-pad:   var(--ph-6);   /* 32  : inside a card, panel or well         */

  /* ── radius ────────────────────────────────────────────────────────── */
  --ph-r-sm:   4px;
  --ph-r-md:   8px;
  --ph-r-lg:   14px;
  --ph-r-tile: 22.27%;          /* app tile, matches the mark's capsule  */
  --ph-r-pill: 999px;

  /* ── measure ───────────────────────────────────────────────────────── */
  --ph-measure:      66ch;
  --ph-measure-lede: 54ch;
  --ph-wrap:         1160px;

  --ph-scheme: light;
  color-scheme: var(--ph-scheme);
}

/* The one media query in this file that is not about colour, and the only
   place a rhythm token is redefined. It declares no colour, so the theming
   contract at the top of this file still holds by inspection: every colour
   is still first declared on bare :root. 640 is the same threshold the
   gutters use, so a page has one phone breakpoint, not two. */
@media (max-width: 640px) {
  :root {
    --ph-band:  var(--ph-8);   /* 72 */
    --ph-stack: var(--ph-7);   /* 48 */
    --ph-block: var(--ph-6);   /* 32 */
    --ph-pad:   var(--ph-5);   /* 24 */
  }
}

/* ── dark: the page becomes the sea ──────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ph-paper:      #081A20;
    --ph-paper-deep: #0C2530;
    --ph-card:       #0E2A34;
    --ph-line:       #1B3742;
    --ph-line-soft:  #122A33;
    --ph-ink:        #E8E4DB;
    --ph-mute:       #93A4A8;

    --ph-deep:       #7FC3D0;   /* primary inverts to a light sea (9.0:1)*/
    --ph-tide:       #A2D6DF;
    --ph-shoal:      #58A0AE;
    --ph-shoal-soft: #0F323D;

    --ph-brass:      #D6A45F;
    --ph-brass-soft: #2A2113;

    --ph-good:       #6FBF97;
    --ph-warn:       #D6A45F;
    --ph-bad:        #E58A70;

    --pp-granted:    #6FBF97;
    --pp-refused:    #E58A70;

    --ph-shadow:      0 1px 1px rgb(0 0 0 / .5), 0 16px 38px -22px rgb(0 0 0 / .9);
    --ph-shadow-soft: 0 1px 2px rgb(0 0 0 / .5);

    --ph-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --ph-paper:      #081A20;
  --ph-paper-deep: #0C2530;
  --ph-card:       #0E2A34;
  --ph-line:       #1B3742;
  --ph-line-soft:  #122A33;
  --ph-ink:        #E8E4DB;
  --ph-mute:       #93A4A8;

  --ph-deep:       #7FC3D0;
  --ph-tide:       #A2D6DF;
  --ph-shoal:      #58A0AE;
  --ph-shoal-soft: #0F323D;

  --ph-brass:      #D6A45F;
  --ph-brass-soft: #2A2113;

  --ph-good:       #6FBF97;
  --ph-warn:       #D6A45F;
  --ph-bad:        #E58A70;

  --pp-granted:    #6FBF97;
  --pp-refused:    #E58A70;

  --ph-shadow:      0 1px 1px rgb(0 0 0 / .5), 0 16px 38px -22px rgb(0 0 0 / .9);
  --ph-shadow-soft: 0 1px 2px rgb(0 0 0 / .5);

  --ph-scheme: dark;
}

/* ═══ base application ════════════════════════════════════════════════ */

body {
  background: var(--ph-paper);
  color: var(--ph-ink);
  font-family: var(--ph-sans);
  font-size: var(--ph-t-body);
  line-height: var(--ph-lh-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

/* Anything a machine owns is set in mono. This is the rule, not a style. */
.ph-machine, code, kbd, samp, pre,
[data-machine] {
  font-family: var(--ph-mono);
  font-size: 0.94em;
  letter-spacing: 0;
}

/* Eyebrows, section numbers, labels: mono, uppercase, wide. */
.ph-label {
  font-family: var(--ph-mono);
  font-size: var(--ph-t-micro);
  letter-spacing: var(--ph-tr-micro);
  text-transform: uppercase;
  color: var(--ph-mute);
}

h1, .ph-display {
  font-size: var(--ph-t-display);
  font-weight: 600;
  line-height: var(--ph-lh-display);
  letter-spacing: var(--ph-tr-display);
  text-wrap: balance;
}

h2 { font-size: var(--ph-t-h2); font-weight: 600; letter-spacing: var(--ph-tr-head); line-height: var(--ph-lh-head); }
h3 { font-size: var(--ph-t-h3); font-weight: 600; letter-spacing: -0.014em; }

p { max-width: var(--ph-measure); }

a {
  color: var(--ph-deep);
  text-decoration-thickness: from-font;
  text-underline-offset: 3px;
}
a:hover { text-decoration-thickness: 2px; }

/* Outline and offset only. Setting border-radius here changes the FOCUSED
   ELEMENT's geometry, not the ring's, so a button visibly reshapes on focus.
   DESIGN-GUIDE section 8 specifies the ring as 2px at 3px offset and nothing more. */
:focus-visible {
  outline: 2px solid var(--ph-deep);
  outline-offset: 3px;
}

/* ── the lockup ──────────────────────────────────────────────────────── */
/* The lockup scales as ONE unit. font-size lives here, on the parent, so the
   mark's 1.42em resolves against the wordmark size the way DESIGN-GUIDE section 3
   specifies ("mark height is 1.42em OF THE WORDMARK", "scale both together, never
   independently"). It previously sat on .ph-wordmark, which left the svg resolving
   1.42em against the inherited 17px body size and rendering at 24px, below the
   28px duotone floor. Override font-size on .ph-lockup itself, never on the parts. */
.ph-lockup { display: inline-flex; align-items: center; gap: .5em; color: var(--ph-deep); font-size: 1.625rem; }
.ph-lockup svg { height: 1.42em; width: auto; display: block; }
.ph-lockup .ph-wordmark {
  font-size: 1em;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ph-ink);
}
.ph-lockup .ph-product {
  font-family: var(--ph-mono);
  font-size: var(--ph-t-micro);
  letter-spacing: var(--ph-tr-micro);
  text-transform: uppercase;
  color: var(--ph-mute);
  border-left: 1px solid var(--ph-line);
  padding-left: 13px;
  margin-left: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
