/* Social — shared design tokens.

   ONE LAW, ONE PALETTE — docs/design.md. This app shipped three visual laws
   and two palettes at once: a Plans day-cell inverted to #17181a while the tab
   bar under it drew #201e1d, and the plan panel's brass was #a8742f while the
   tab bar's was #b07b33. docs/design.md § THE GROUNDS, § THE ACCENT and
   § THE CATEGORIES are now the only place a role is named, and this file is
   the only place a role has a value.

   THE ROLES ARE APPLE'S, and the reason is structural rather than a taste: the
   app is built on MapKit and reads as a native iOS app, so the grounds are
   systemGroupedBackground, the accent is systemIndigo and every category hue
   is one Apple system colour — which is what lets a pin sit beside Apple Maps'
   own restaurant and bar pins without clashing.

   FOUR INK LEVELS, NOT THREE. The old law had three and the third was doing
   two jobs at once — carrying real information (times, prices, distances) and
   being the quiet decorative tone (separators, disabled) — so it was tuned for
   the wrong one. --ink-quiet carries information and never goes below the
   value below it; --ink-faint is never text a person is expected to read.

   NIGHT IS DECLARED AND OFF. The `[data-theme="night"]` block below is a
   second derivation rather than an inversion, and it is gated on the ATTRIBUTE
   ONLY: src/index.html carries `data-theme="day"` and there is deliberately no
   `prefers-color-scheme` rule, because no surface in this app has been checked
   in dark. One attribute flip turns it on in a later pass. That is the whole
   mechanism. */

:root {
  /* ==========================================================
     THE DAY PALETTE — the law's own hexes, and the only place
     a value lives. Every color in the app flows from these
     tokens; there are no hardcoded colors outside this block
     and its night twin.
     ========================================================== */

  /* page + surfaces

     THE DAY GROUND IS SLATE AND NO LONGER NEUTRAL. Every level below except
     --surface moved one step toward blue: a neutral grey ground under a map
     whose water and parks are the only saturated things on the screen reads
     as the absence of a decision, and the app's one accent is indigo. The
     ground is now the same family as the accent rather than a colour nobody
     picked.

     --surface DOES NOT MOVE. #ffffff is the card, and it is what
     tests/warmer-heat.spec.ts asserts the canvas renderer's PAPER_INK
     against — the one ink that renderer cannot ask the stylesheet for at
     paint time. A tinted card would also be the one surface in this app that
     a photograph sits on. */
  --page: #eceef4;            /* systemGroupedBackground, cooled to slate */
  --surface: #ffffff;         /* cards, list rows */
  --surface-sunken: #e0e3ec;  /* inputs, wells inside cards */
  --border: #d6dae4;          /* visible card and input borders */
  --border-strong: #9aa0ae;   /* hairlines that must read as lines: day
                                 dividers, the calendar grid, table rules */

  /* ink — four levels, each with one job. See the header. Slate too, and the
     top level is no longer pure black: #0b1017 is a near-black that belongs
     to the ground under it, and it reads 16.5:1 on --page. */
  --ink: #0b1017;             /* titles, and what a person came to read */
  --ink-soft: #7d828e;        /* venue lines, sub-copy, second lines */
  --ink-quiet: #6e737f;       /* times, prices, distances, section labels —
                                 CARRIES INFORMATION, never taken lower */
  --ink-faint: #b2b7c3;       /* separators, disabled, decoration — NEVER
                                 text a person is expected to read */

  /* indigo brand — systemIndigo, and it does exactly one job: it marks what
     is yours and what is live. Brass is retired, for a structural reason
     worth recording: Apple Maps' ground is a warm pale beige and brass is the
     same family, so a brass pin sank into the terrain instead of sitting on
     it — and brass was also Music's category hue, so selection and "this is a
     concert" said the same thing. */
  --brand: #5856d6;           /* primary action, current tab, selection, links */
  --brand-strong: #4a48c4;    /* hover / pressed / text-on-light accents */

  /* status */
  --accent: #ff3b30;          /* the one loud color — alert, errors, the NEW tag */
  --ok: #34c759;              /* success confirmations, free shows */

  /* GOLD, AND IT IS A REAL COLOUR NOW. The golden ticket's gold was DERIVED
     from --brand — `color-mix(in srgb, var(--brand) 76%, var(--surface))`, in
     src/social.css and again in src/feed.css. That worked while --brand was
     brass: mixing brass toward white gives leaf. --brand is indigo, and mixing
     indigo toward white gives LAVENDER, so every golden ticket in the app has
     been shipping pale purple. A ticket that is not golden is a bug in the one
     object whose entire meaning is its colour, so the gold stops being a
     function of the accent and becomes a value of its own — which is also what
     stops the next re-hue of --brand from repainting it again.

     It is a leaf gold rather than a metallic yellow: it carries text on the
     feed card's dark ground and sits on Apple Maps' warm beige without sinking
     into it, which is the same argument that retired brass. */
  --gold: #c9922f;            /* the golden ticket, and nothing else */

  /* cold — the one COOL color, and it names one idea: ground with nobody on
     it. The map's warmer demo washes the basemap in it and paints its
     quietest districts with it; heat stays --brand's, because a person is
     warmth. Deliberately a slate BLUE and not a teal: --ok is what this app
     spends on a FRIEND, and cold that could be mistaken at a glance for
     somebody you know would be a bug rather than a style. It is its own
     token instead of a borrowed category hue for the reason the group below
     states — those are read through src/lib/categories.ts and mean a KIND OF
     EVENT, so a re-hue there must never repaint the map.

     UNCHANGED BY THE PALETTE PASS. Everything around it got warmer or louder;
     this one did not move, because its whole job is to be the temperature
     nothing is happening at. */
  --cold: #4a6fa5;

  /* category hues — read through src/lib/categories.ts, which is the one list
     mapping category ids onto these. Ten categories, ten Apple system hues,
     one each; blue and indigo are reserved, which is exactly what leaves room
     for ten. Where a category hue may appear: the map pin, its glyph, a
     card's tag dot, a filter chip's dot. That is the entire list — never a
     button, a wash, a card fill, a header or a selected state, because a
     category is information and not emphasis. */
  --cat-music: #ff2d55;       /* systemPink */
  --cat-nightlife: #af52de;   /* systemPurple */
  --cat-food: #ff9500;        /* systemOrange */
  --cat-water: #32ade6;       /* systemCyan */
  --cat-comedy: #ffcc00;      /* systemYellow — takes DARK ink; white on
                                 yellow fails contrast on both grounds */
  --cat-games: #34c759;       /* systemGreen */
  --cat-arts: #a2845e;        /* systemBrown */
  --cat-fitness: #00c7be;     /* systemMint */
  --cat-sports: #ff3b30;      /* systemRed */
  --cat-market: #30b0c7;      /* systemTeal */
  --cat-other: #8e8e93;       /* systemGray */
  /* RETIRED, PENDING THE VOCABULARY CHANGE. docs/design.md names ten
     categories and 'family' is not one of them — but src/lib/categories.ts
     still lists it and still renders `var(--cat-family)`, so deleting the
     token here would draw a chip dot in no colour at all, which reads as a
     rendering bug rather than as a retirement. It dies with the vocabulary in
     its own lane; until then it is systemGray, the same as --cat-other. */
  --cat-family: #8e8e93;

  /* the one shadow: soft ink, for cards and raised menus */
  --shadow: rgba(45, 43, 43, 0.12);

  /* type — SAN FRANCISCO, VIA THE SYSTEM STACK, and it is the one face here
     that is loaded by not being loaded. docs/design.md § TYPE has said so
     since the law was written — "A custom face is the loudest single tell
     that an app is not native" — while this file went on declaring Archivo
     and the shell went on fetching it from Google Fonts. Both loads are gone.

     THE THREE NAMES STAY, because they carry 230 declarations between them
     and renaming buys churn. All three resolve to ONE stack, the law's own
     character for character, and what they mean is a ROLE and not a face:

       --font-display  the poster voice. WEIGHT is what makes a display line
                       now, and the weight is written at every site already.
       --font-body     running text, and the app's default.
       --font-mono     TABULAR, NOT A SECOND FACE — the places whose subject
                       is a NUMBER, which is why the rules reading it carry
                       font-variant-numeric. Nothing in this app wants a
                       fixed advance, and the retired chain gave none either:
                       it began 'Archivo', so ui-monospace was never reached.

     NO "SF Pro Display" FOR THE DISPLAY TOKEN, and no variable-axis settings
     anywhere. Those are the retired discrete optical cuts; modern SF is one
     variable face that interpolates optical size from the point size, and
     naming a cut — or an axis — fights it. */
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;
  --font-mono: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;

  /* 8px spacing grid */
  --s1: 8px;
  --s2: 16px;
  --s3: 24px;
  --s4: 32px;
  --s5: 40px;

  --radius: 6px;
  --radius-lg: 10px;
  --touch: 48px; /* minimum touch target */

  /* The fixed bottom tab bar's height, EXCLUDING the safe-area strip beneath
     it. A token rather than a number in three rules, because three things
     have to agree about it: the bar's own box, the page's bottom padding (so
     the last card is not sat on), and the Ask composer's sticky offset (so it
     rides above the bar rather than behind it). */
  --tabbar-h: 58px;

  /* The bar treatment, shared by the app bar and the tab bar so the two edges
     of the app match: the page color, thinned, with a blur behind it where
     the browser supports one. color-mix rather than a fifth surface hex —
     this file's no-hardcoded-color contract holds. */
  --bar-bg: color-mix(in srgb, var(--page) 88%, transparent);

  /* ── THE DARK GROUND — the poster's own, and it does not follow the theme ──
     docs/design.md § THE GROUNDS, THE DARK GROUND. The two POSTER surfaces —
     the feed's stream and the Plans day view's part stack, one card component
     between them — are drawn on the NIGHT ground whichever theme the html
     attribute names: the card is the screen and the chrome floats over it. So
     their roles are declared ONCE, here, at the night table's values to the
     hex, and are NOT restated in the night block below, because a ground that
     does not follow the theme has no second value to restate. Eight roles —
     the night ground's four levels and its four inks — under a prefix of their
     own, so a poster rule can never be reading the page's ground by accident
     and a page rule can never be reading the poster's. tests/design-law.spec.ts
     reads each value out of the law's own table and asserts it here and
     nowhere else. src/feed.css is the one sheet that spends them. */
  --poster-page: #000000;
  --poster-surface: #1c1c1e;
  --poster-surface-sunken: #2c2c2e;
  --poster-border: #48484d;
  --poster-ink: #ffffff;
  --poster-ink-soft: #b3b3b8;
  --poster-ink-quiet: #77777c;
  --poster-ink-faint: #48484d;
}

/* ── NIGHT — DECLARED, AND DELIBERATELY NOT ON ───────────────────────────
   A second derivation, not an inversion: the same value reads darker against
   black, so every level is re-picked rather than flipped. Gated on the
   attribute ALONE. src/index.html ships `data-theme="day"` and there is no
   `prefers-color-scheme` rule in this file on purpose — no surface in this
   app has been checked in dark, and a media query would turn all of them on
   at once, on somebody else's phone, without anybody having looked. Flipping
   the one attribute is the whole switch.

   Only the ROLES that change are restated. --border-strong, --cold, --shadow,
   the faces, the steps, the radii and --tabbar-h are ground-independent and
   are declared once, above.

   IT IS STILL NEUTRAL UNDER A SLATE DAY, AND THAT IS A CHOICE. The day ground
   cooled to slate in the pass that deleted the second palette; this block did
   not move a value, because night is a SECOND DERIVATION rather than a tint of
   the first — every level here has to be re-picked against black, and no
   surface in this app has been looked at on this ground yet. Cooling these by
   the same arithmetic would be guessing at eleven colours nobody has seen.
   Night gets its own pass; until then the mismatch is dormant, because the
   attribute that would show it is never set. */

[data-theme="night"] {
  --page: #000000;
  --surface: #1c1c1e;
  --surface-sunken: #2c2c2e;
  --border: #48484d;

  --ink: #ffffff;
  --ink-soft: #b3b3b8;
  --ink-quiet: #77777c;
  --ink-faint: #48484d;

  --brand: #7d7bef;
  --brand-strong: #9695f2;

  --accent: #ff453a;
  --ok: #30d158;

  /* Lifted on black, like every other pigment here — the day value reads as
     brown against the night ground rather than as gold. */
  --gold: #e0b45c;

  --cat-music: #ff375f;
  --cat-nightlife: #c56bf5;
  --cat-food: #ff9f0a;
  --cat-water: #64d2ff;
  --cat-comedy: #ffd60a;
  --cat-games: #30d158;
  /* The single deviation from Apple's own dark value: systemBrown goes muddy
     on black, so arts is pushed past it. */
  --cat-arts: #c6a47c;
  --cat-fitness: #63e6e2;
  --cat-sports: #ff453a;
  --cat-market: #40c8e0;
  --cat-other: #a0a0a6;
}

/* ── REDUCED TRANSPARENCY: THE MATERIAL GETS ITS OPAQUE TWIN ─────────────
   docs/design.md § THE MATERIAL: "Every glass token has an opaque twin and it
   is not optional." We cannot read iOS's transparency slider, so a reader who
   has turned it down gets the ground itself rather than a thinned one. The
   BLUR is not touched here and that is deliberate: three specs assert
   `backdrop-filter: blur(10px)` verbatim against the sheets that declare it,
   and dropping the filter is that pass's work rather than this one's. */

@media (prefers-reduced-transparency: reduce) {
  :root {
    --bar-bg: var(--page);
  }
}

/* ── INCREASED CONTRAST ─────────────────────────────────────────────────
   Two roles move and no third: the hairline becomes the one that reads as a
   line, and the quiet level gives up being quiet. On the night ground that is
   a straight lift (--ink-soft is the lighter of the two against black); on
   day the two sit within 15 points of each other, so it is a small move
   rather than a dramatic one — the level that carries information is already
   the darker of the pair by the law's own tuning. */

@media (prefers-contrast: more) {
  :root {
    --border: var(--border-strong);
    --ink-quiet: var(--ink-soft);
  }
}

/* --- reduced motion: disable every animation --- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}
