/* ============================================================================
   Dama Pa More — design tokens.  GENERATED FILE, DO NOT EDIT.

   Source:    tools/tokens/skins.json
   Regenerate: node tools/tokens/gen.mjs

   Every value the two skins disagree about lives here and nowhere else.
   ========================================================================== */

/* ── Damahan sa Gabi — the primary skin ───────────────────────────── */
/* The locked visual identity: hardwood + brass, indigo night, jade = your turn, coral = opponent, cream pieces and text. */
:root{
  color-scheme: dark;

  /* Night — background depths */
  --night-950:#0E1120;  /* deepest, page base */
  --night-900:#12162A;  /* app background */
  --night-800:#161C34;  /* subtle raised background */

  /* Raised surfaces (indigo) */
  --surface:#1C2340;    /* cards, sheets */
  --surface-2:#232B4E;  /* nested / hovered surface */
  --surface-3:#2C355F;  /* highest elevation, popovers */

  /* Hardwood board. The first four are what a BOARD SKIN overrides — a skin is
     these four custom properties set on the .board element and nothing else
     (js/cosmetics.js applySkin). Square geometry and every state affordance
     (.is-selected / .is-dest / .is-capture / .is-last / .is-hint) stay owned by
     the theme, so a cosmetic cannot make the board easier or harder to read.

     WHO WINS, the app skin or the equipped cosmetic: a PURCHASED board is its
     own art and looks the same in both skins - you paid for that wood. The FREE
     DEFAULT is not a purchase, it is the theme's own board, so it follows the
     skin and these values ARE it. Without that rule every fiesta value below is
     dead on arrival: applySkin would write kamagong's night hexes over them the
     moment the catalogue loads, and the hero screen would stay dark in a light
     skin. Enforced in js/cosmetics.js (skip the two free ids) and in Dart by
     BoardSkin.themed / PieceSkin.themed. */
  --wood-dark:#4A2F1E;       /* kamagong — dark (playable) sq */
  --wood-dark-2:#5A3A25;     /* kamagong highlight */
  --wood-light:#D8B27C;      /* narra tan — light square */
  --wood-light-2:#C99A5B;    /* narra shadow */
  --wood-light-hi:#E7C592;   /* narra radial highlight — the lattice field's innermost stop */
  --wood-frame-top:#3A2416;  /* board bezel, gradient head */
  --wood-frame:#2E1D12;      /* board bezel, gradient foot */
  --wood-line:#2E1D12;       /* lattice line + node dots (Pinoy Dama); the square boards do not use it */

  /* Disc fills. Likewise: a PIECE SKIN is these six properties on .board. They
     were literal hex inside the .disc gradients, which is why a piece set could
     not be themed at all. `mine`/`opp` are VIEWER-RELATIVE (board.js paints by
     seat, not by colour), which is exactly why local-view-only cosmetics drop in
     with no board-logic change: you restyle both sides of YOUR screen only. */
  --disc-mine-hi:#FFFDF4;
  --disc-mine-mid:var(--cream);
  --disc-mine-lo:#E4D6B4;
  --disc-opp-hi:#FF9C82;
  --disc-opp-mid:var(--coral);
  --disc-opp-lo:var(--coral-deep);

  /* Generals token gradients — one pair per SIDE, never per rank. Kept here
     beside the disc fills because they are the same piece set seen on the other
     board, and PieceSkin.themed has to be TOTAL: a themed default that re-tinted
     the draughts disc and left the Generals token on the night palette would put
     two art directions on one screen. There is deliberately no per-rank input —
     a rank tell on a token is a release blocker, so the token type cannot express
     one (progress/cosmetics.dart, invariant 4). */
  --token-mine-top:#FBF3DE;                 /* my token, gradient head */
  --token-mine-bottom:var(--disc-mine-lo);  /* my token, gradient foot */
  --token-opp-top:var(--coral);             /* their token, gradient head */
  --token-opp-bottom:#BE4028;               /* their token, gradient foot */

  /* Game of the Generals — the felt table. A THIRD board surface, and the
     only place the app leaves hardwood. It stays pine in both skins: a felt
     table is a felt table, and the ranks on it are read as light-on-dark in
     the spec's light screens too. The star is the rank glyph's own gold and
     is NOT --brass: it sits on that dark felt in both skins, so it must not
     follow a token Fiesta re-points at ink. */
  --gg-field-top:#1D2B22;     /* felt, gradient head */
  --gg-field-bottom:#141F19;  /* felt, gradient foot */
  --gg-star:#C8952E;          /* rank star on the felt — gold on dark in BOTH skins */

  /* Accents */
  --brass:#E3A730;                   /* primary accent, ranked gold */
  --brass-bright:#F4C049;            /* crown highlight, focus */
  --brass-fill:var(--brass-bright);  /* gradient HEAD of a brass fill — a button, an active segment, an avatar. Distinct from --brass-bright, which Fiesta re-points at ink: `bright -> deep` there is a DARK-to-gold ramp carrying --on-brass text, and the label disappears into the top of its own pill */
  --brass-deep:#B8841F;              /* brass shadow / pressed */
  --jade:#28C2A0;                    /* your-turn, online, positive */
  --jade-deep:#1E9C81;
  --jade-bright:#3ADFBB;             /* gradient top-light; collapses to --jade in fiesta, whose buttons are flat fills with a hard slab rather than gradients */
  --coral:#F26B4E;                   /* opponent, alert */
  --coral-deep:#D2492F;
  --coral-bright:#FF8468;            /* gradient top-light */
  --cream:#F5ECD6;                   /* my pieces, light text */
  --jade-ink:var(--jade);            /* accent as INK — one hex cannot be both fill and label on a light ground */
  --coral-ink:var(--coral);          /* accent as INK — one hex cannot be both fill and label on a light ground */

  /* Text roles */
  --text:#F5ECD6;
  --text-strong:#FFF8EA;
  --text-muted:rgba(245,236,214,.66);
  --text-faint:rgba(245,236,214,.56);  /* .40 failed AA at 10-11px */
  --on-brass:#2A1B06;                  /* text on brass fills */
  --on-jade:#04231C;
  --on-coral:#3A0E05;
  --on-cream:#2A1B06;

  /* Status */
  --win:#28C2A0;
  --lose:#F26B4E;
  --warn:#F4C049;
  --info:#7FA8FF;

  /* Lines & separators */
  --hairline:rgba(244,192,73,.16);      /* brass hairline motif */
  --line:rgba(245,236,214,.10);
  --line-strong:rgba(245,236,214,.18);
  --stroke:1px;                         /* border width — a structural axis, not a colour */

  /* Radius */
  --r-xs:6px;
  --r-sm:10px;
  --r-md:14px;
  --r-lg:20px;
  --r-xl:28px;
  --r-pill:999px;

  /* Spacing scale (4pt) */
  --s-1:4px;
  --s-2:8px;
  --s-3:12px;
  --s-4:16px;
  --s-5:20px;
  --s-6:24px;
  --s-8:32px;
  --s-10:40px;
  --s-12:48px;

  /* Elevation */
  --shadow-sm:0 1px 2px rgba(0,0,0,.40);
  --shadow-md:0 6px 18px rgba(0,0,0,.45);
  --shadow-lg:0 18px 48px rgba(0,0,0,.55);
  --shadow-brass:0 6px 20px rgba(227,167,48,.35);
  --shadow-jade:0 6px 20px rgba(40,194,160,.35);
  --shadow-coral:0 6px 20px rgba(242,107,78,.30);
  --disc-shadow:0 4px 8px rgba(0,0,0,.5);          /* the drop under a playing piece. Gabi lifts it off a dark board with a blur; Fiesta cannot separate cream pieces from a cream board by colour at all, so the drop becomes a HARD SLAB and does the bounding — see the bounded-piece exemption in app/test/cosmetics_equip_test.dart */
  --edge-top:inset 0 1px 0 rgba(255,255,255,.08);  /* top bevel highlight */

  /* Type — rounded-geometric display, robust offline stack */
  --font-display:"SF Pro Rounded","Nunito","Inter",system-ui,-apple-system,"Segoe UI Rounded","Segoe UI",Roboto,sans-serif;
  --font-text:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-num:"SF Pro Rounded","Inter",system-ui,sans-serif;                                                                  /* pair w/ .tnum */

  /* Type scale */
  --fs-display:34px;
  --lh-display:1.05;
  --fs-h1:26px;
  --lh-h1:1.12;
  --fs-h2:20px;
  --lh-h2:1.18;
  --fs-h3:17px;
  --lh-h3:1.25;
  --fs-body:15px;
  --lh-body:1.45;
  --fs-sm:13px;
  --lh-sm:1.4;
  --fs-xs:11px;
  --lh-xs:1.35;

  /* Motion */
  --ease:cubic-bezier(.2,.7,.25,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-fast:120ms;
  --dur:200ms;
  --dur-slow:340ms;

  /* Banig weave
     A 45/-45 cross-hatch at <=3% opacity — texture you feel, not see (contract
     section 4). Multi-line on purpose: it is two stacked gradients, and it is the
     one token whose value spans lines, which is exactly how it went missing when
     this file was first extracted by regex. Consumed by .banig, .phone::after and
     shell.css .app-shell::after. */
  --banig:
    repeating-linear-gradient( 45deg, rgba(245,236,214,.030) 0 2px, transparent 2px 8px),
    repeating-linear-gradient(-45deg, rgba(244,192,73,.022) 0 2px, transparent 2px 8px);
}


/* ── Fiesta Play ─────────────────────────────────────────────── */
/* The bright direction. Filled in the following commit; see docs/contracts/00-design-system.md. */
:root[data-theme="fiesta"]{
  color-scheme: light;

  /* Night — background depths */
  --night-950:#F7ECD2;  /* deepest, page base */
  --night-900:#FBF4E4;  /* app background */
  --night-800:#FDF9ED;  /* subtle raised background */

  /* Raised surfaces (indigo) */
  --surface:#FFFDF6;    /* cards, sheets */
  --surface-2:#F7EDD9;  /* nested / hovered surface */
  --surface-3:#FFFFFF;  /* highest elevation, popovers */

  /* Hardwood board. The first four are what a BOARD SKIN overrides — a skin is
     these four custom properties set on the .board element and nothing else
     (js/cosmetics.js applySkin). Square geometry and every state affordance
     (.is-selected / .is-dest / .is-capture / .is-last / .is-hint) stay owned by
     the theme, so a cosmetic cannot make the board easier or harder to read.

     WHO WINS, the app skin or the equipped cosmetic: a PURCHASED board is its
     own art and looks the same in both skins - you paid for that wood. The FREE
     DEFAULT is not a purchase, it is the theme's own board, so it follows the
     skin and these values ARE it. Without that rule every fiesta value below is
     dead on arrival: applySkin would write kamagong's night hexes over them the
     moment the catalogue loads, and the hero screen would stay dark in a light
     skin. Enforced in js/cosmetics.js (skip the two free ids) and in Dart by
     BoardSkin.themed / PieceSkin.themed. */
  --wood-dark:#B08350;       /* kamagong — dark (playable) sq */
  --wood-dark-2:#BB9469;     /* kamagong highlight */
  --wood-light:#F1E3C2;      /* narra tan — light square */
  --wood-light-2:#DDB877;    /* narra shadow */
  --wood-light-hi:#F6EACC;   /* narra radial highlight — the lattice field's innermost stop */
  --wood-frame-top:#9E6A40;  /* board bezel, gradient head */
  --wood-frame:#7E5533;      /* board bezel, gradient foot */
  --wood-line:#96713F;       /* lattice line + node dots (Pinoy Dama); the square boards do not use it */

  /* Disc fills. Likewise: a PIECE SKIN is these six properties on .board. They
     were literal hex inside the .disc gradients, which is why a piece set could
     not be themed at all. `mine`/`opp` are VIEWER-RELATIVE (board.js paints by
     seat, not by colour), which is exactly why local-view-only cosmetics drop in
     with no board-logic change: you restyle both sides of YOUR screen only. */
  --disc-mine-lo:#DDC9A0;
  --disc-opp-hi:#FF8A66;

  /* Generals token gradients — one pair per SIDE, never per rank. Kept here
     beside the disc fills because they are the same piece set seen on the other
     board, and PieceSkin.themed has to be TOTAL: a themed default that re-tinted
     the draughts disc and left the Generals token on the night palette would put
     two art directions on one screen. There is deliberately no per-rank input —
     a rank tell on a token is a release blocker, so the token type cannot express
     one (progress/cosmetics.dart, invariant 4). */
  --token-mine-top:#F9EDD0;    /* my token, gradient head */
  --token-opp-bottom:#B03923;  /* their token, gradient foot */

  /* Game of the Generals — the felt table. A THIRD board surface, and the
     only place the app leaves hardwood. It stays pine in both skins: a felt
     table is a felt table, and the ranks on it are read as light-on-dark in
     the spec's light screens too. The star is the rank glyph's own gold and
     is NOT --brass: it sits on that dark felt in both skins, so it must not
     follow a token Fiesta re-points at ink. */
  --gg-field-top:#1E332F;     /* felt, gradient head */
  --gg-field-bottom:#16241F;  /* felt, gradient foot */

  /* Accents */
  --brass:#FFC530;            /* primary accent, ranked gold */
  --brass-bright:#9E5124;     /* crown highlight, focus */
  --brass-fill:var(--brass);  /* gradient HEAD of a brass fill — a button, an active segment, an avatar. Distinct from --brass-bright, which Fiesta re-points at ink: `bright -> deep` there is a DARK-to-gold ramp carrying --on-brass text, and the label disappears into the top of its own pill */
  --brass-deep:#D89B00;       /* brass shadow / pressed */
  --jade:#2E9E8F;             /* your-turn, online, positive */
  --jade-deep:#1F7A6E;
  --jade-bright:var(--jade);  /* gradient top-light; collapses to --jade in fiesta, whose buttons are flat fills with a hard slab rather than gradients */
  --coral:#E4573D;            /* opponent, alert */
  --coral-deep:#C43F27;
  --coral-bright:#FF8A66;     /* gradient top-light */
  --cream:#F3E6C8;            /* my pieces, light text */
  --jade-ink:#1A6B60;         /* accent as INK — one hex cannot be both fill and label on a light ground */
  --coral-ink:#B33520;        /* accent as INK — one hex cannot be both fill and label on a light ground */

  /* Text roles */
  --text:#3D2C1E;
  --text-strong:#3D2C1E;
  --text-muted:rgba(61,44,30,.75);
  --text-faint:rgba(61,44,30,.70);  /* .40 failed AA at 10-11px */
  --on-brass:#4A3200;               /* text on brass fills */
  --on-cream:#4A3200;

  /* Status */
  --win:#2E9E8F;
  --lose:#E4573D;
  --warn:#8A6200;
  --info:#4462B0;

  /* Lines & separators */
  --hairline:#F4ECD9;     /* brass hairline motif */
  --line:#EADFC6;
  --line-strong:#B7A075;
  --stroke:2px;           /* border width — a structural axis, not a colour */

  /* Radius */
  --r-lg:18px;
  --r-xl:24px;

  /* Elevation */
  --shadow-sm:0 2px 0 var(--line-strong);
  --shadow-md:0 4px 0 var(--line-strong);
  --shadow-lg:0 8px 0 var(--line-strong), 0 18px 30px rgba(70,44,20,.35);
  --shadow-brass:0 4px 0 var(--brass-deep);
  --shadow-jade:0 2px 0 var(--jade-deep);
  --shadow-coral:0 2px 0 var(--coral-deep);
  --disc-shadow:0 3px 0 rgba(120,84,40,.55);                               /* the drop under a playing piece. Gabi lifts it off a dark board with a blur; Fiesta cannot separate cream pieces from a cream board by colour at all, so the drop becomes a HARD SLAB and does the bounding — see the bounded-piece exemption in app/test/cosmetics_equip_test.dart */
  --edge-top:inset 0 2px 3px rgba(255,255,255,.70);                        /* top bevel highlight */

  /* Type — rounded-geometric display, robust offline stack */
  --font-display:"Titan One","SF Pro Rounded","Nunito",system-ui,-apple-system,"Segoe UI Rounded","Segoe UI",Roboto,sans-serif;
  --font-text:"Nunito",system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-num:"Nunito",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;                                                      /* pair w/ .tnum */

  /* Type scale */
  --lh-display:1;
  --lh-h1:1.1;
  --lh-h2:1.1;
  --lh-h3:1.1;
  --fs-body:14px;
  --lh-body:1.5;
  --fs-sm:12px;
  --lh-sm:1.2;
  --fs-xs:10.5px;
  --lh-xs:1.25;

  /* Banig weave
     A 45/-45 cross-hatch at <=3% opacity — texture you feel, not see (contract
     section 4). Multi-line on purpose: it is two stacked gradients, and it is the
     one token whose value spans lines, which is exactly how it went missing when
     this file was first extracted by regex. Consumed by .banig, .phone::after and
     shell.css .app-shell::after. */
  --banig:none;
}


/* ── Legacy light — SUPERSEDED, still emitted ──────────────────────────── */
/* The [data-theme="light"] block as shipped. SUPERSEDED by the fiesta skin but still emitted, because web/js/state.js accepts theme:light and web/js/screens/settings.js still writes it. Delete this together with the light->fiesta migration, not before, or anyone who picked Light drops to unstyled dark for a release. */
:root[data-theme="light"]{
  color-scheme: light;
  --night-950:#EDE6D4;
  --night-900:#F3ECDC;
  --night-800:#E9E0CC;
  --surface:#FFFFFF;
  --surface-2:#F6EFDE;
  --surface-3:#FBF5E7;
  --text:#2A2233;
  --text-strong:#171021;
  --text-muted:rgba(42,34,51,.66);
  --text-faint:rgba(42,34,51,.66);
  --cream:#F5ECD6;
  --hairline:rgba(184,132,31,.28);
  --line:rgba(42,34,51,.10);
  --line-strong:rgba(42,34,51,.16);
  --shadow-sm:0 1px 2px rgba(80,60,20,.14);
  --shadow-md:0 6px 18px rgba(80,60,20,.16);
  --shadow-lg:0 18px 48px rgba(80,60,20,.20);
  --edge-top:inset 0 1px 0 rgba(255,255,255,.6);
}
