/* ==========================================================================
   tokens.css — the single source of design truth
   --------------------------------------------------------------------------
   Every other stylesheet reads ONLY --tcg-* custom properties. No component
   file may hard-code a colour, a font size, or a spacing value.

   PORTING TO THE THEME
   At port time this file becomes a ~40-line alias layer over theme.json's
   generated properties, e.g.

       --tcg-space-md:    var(--wp--preset--spacing--50);
       --tcg-color-brand: var(--wp--preset--color--brand);

   and nothing else in assets/css/ changes. That is the whole theme.json
   integration cost. The mapping table lives at the bottom of this file.

   DARK MODE
   theme.json's settings.color.palette is a flat list of single values and
   CANNOT express a light/dark pair. So theme.json carries the LIGHT palette
   only (it is also what the block editor offers editors for article
   content), and dark stays a prefers-color-scheme block re-binding the same
   --tcg-* names. Never give a colour its only definition inside dark.

   REGISTER
   This is a Japanese information site, not a Western SaaS dashboard.
   Density over whitespace; visible borders and tinted fills do the
   structural work rather than shadows and generous margins.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* ---------------------------------------------------------------------
     SURFACES & TEXT — light
     Light-grey ground behind white cards is the standard JP info-site
     treatment. Borders here are load-bearing, not whispers.
     --------------------------------------------------------------------- */
  --tcg-color-bg:             #f2f4f7;
  --tcg-color-surface:        #ffffff;
  --tcg-color-surface-2:      #eaeef3;   /* chip off-state, table zebra, dl stripes */
  --tcg-color-surface-sunken: #e3e8ee;   /* inset wells, code blocks */
  --tcg-color-border:         #d5dbe3;
  --tcg-color-border-strong:  #aab4c2;
  --tcg-color-text:           #1a1d21;
  --tcg-color-text-muted:     #5a6470;
  --tcg-color-text-faint:     #8a94a2;
  --tcg-color-text-invert:    #ffffff;

  /* ---------------------------------------------------------------------
     BRAND
     Deep information-blue: reads "trustworthy reference" in JP, and sits
     far from every status hue. Doubles as the CTA colour — a separate
     orange accent would muddy against amber and red.
     --------------------------------------------------------------------- */
  --tcg-color-brand:          #1450a3;
  --tcg-color-brand-strong:   #0f3d7d;   /* hover / active */
  --tcg-color-brand-soft:     #e7effa;   /* active chip fill, section band */
  --tcg-color-brand-contrast: #ffffff;

  /* ---------------------------------------------------------------------
     STATUS
     Colour is never the only channel: each status also carries a text
     label, a glyph, and a distinct card border-style. See components.css.
     --------------------------------------------------------------------- */
  --tcg-color-open-fg:     #0f7b3d;
  --tcg-color-open-bg:     #e4f4ea;
  --tcg-color-open-bd:     #9dd4b4;

  --tcg-color-upcoming-fg: #0e6f80;
  --tcg-color-upcoming-bg: #e0f2f5;
  --tcg-color-upcoming-bd: #9ad0da;

  --tcg-color-waiting-fg:  #8a5a00;
  --tcg-color-waiting-bg:  #fdf1d8;
  --tcg-color-waiting-bd:  #e6c67e;

  --tcg-color-ended-fg:    #5a6470;
  --tcg-color-ended-bg:    #eaeef3;
  --tcg-color-ended-bd:    #ccd3dc;

  /* ---------------------------------------------------------------------
     URGENCY — RESERVED.
     Red is never decorative on this site. It means one thing: this
     deadline is 24 hours or less away. Using it anywhere else devalues
     the only signal that must cut through.
     --------------------------------------------------------------------- */
  --tcg-color-urgent-fg:   #c1272d;
  --tcg-color-urgent-bg:   #fdeaea;
  --tcg-color-urgent-bd:   #f0b3b5;

  /* ---------------------------------------------------------------------
     AD LABEL — compliance with the Japanese stealth-marketing rules
     A solid dark pill. Deliberately NOT brand-coloured (that would read as
     an endorsement) and NOT a pastel tint (that would blend into the
     status pills). Distinguishable by treatment alone, so it survives
     colour-blindness, greyscale and printing.
     --------------------------------------------------------------------- */
  --tcg-color-ad-bg:       #333944;
  --tcg-color-ad-fg:       #ffffff;
  --tcg-color-ad-bd:       #333944;

  /* --- ratings --- */
  --tcg-color-star-on:     #e8a300;
  --tcg-color-star-off:    #ccd3dc;

  /* --- focus ring: distinct from brand so it is never ambiguous --- */
  --tcg-color-focus:       #1a6fe8;

  /* ---------------------------------------------------------------------
     ARTICLE REGISTER — JP blog conventions
     Marker highlights and callout box tints. Used only inside articles;
     the board never touches these.
     --------------------------------------------------------------------- */
  --tcg-color-marker-yellow: #fff29a;
  --tcg-color-marker-pink:   #ffd0e0;

  --tcg-color-point-bg: #eef7ff;  --tcg-color-point-bd: #7fb3e8;
  --tcg-color-warn-bg:  #fff4e5;  --tcg-color-warn-bd:  #e8a33d;
  --tcg-color-sum-bg:   #f0f7ee;  --tcg-color-sum-bd:   #83b96f;
  --tcg-color-check-bg: #f4f1fb;  --tcg-color-check-bd: #a38fd8;

  --tcg-color-balloon-bg: #eef1f6;
  --tcg-color-backdrop:   rgba(16, 19, 25, .55);

  /* =====================================================================
     TYPOGRAPHY
     ===================================================================== */

  /* "Yu Gothic Medium" MUST precede "Yu Gothic". Yu Gothic Regular is
     notoriously spindly and low-contrast on Windows, which is this
     audience's most common environment; naming the Medium face first
     (with body font-weight 500) is the standard fix. Skipping it makes
     the site look broken to a large share of readers.

     NO WEB FONTS, EVER. Even aggressively subset Japanese webfonts run
     300KB-1MB, and font-display:swap on Japanese text produces violent
     reflow. CLAUDE.md names speed as the biggest theme-side SEO factor;
     this is where that is cashed in. */
  --tcg-font-sans:
    -apple-system, BlinkMacSystemFont,
    "Hiragino Kaku Gothic ProN", "Hiragino Sans",
    "Yu Gothic Medium", "Yu Gothic",
    "Noto Sans JP", "Meiryo",
    sans-serif;

  --tcg-font-mono:
    ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;

  /* Base 16px, ratio approx 1.2 — deliberately denser than 1.25, because
     Japanese glyphs eat horizontal space fast at larger sizes. */
  --tcg-fs-2xs:      0.6875rem;  /* 11px — ad badge, verified line */
  --tcg-fs-xs:       0.75rem;    /* 12px — taxonomy chips, counts, eyebrow */
  --tcg-fs-sm:       0.8125rem;  /* 13px — schedule dl, note, captions */
  --tcg-fs-base:     1rem;       /* 16px — body, hook */
  --tcg-fs-lg:       1.125rem;   /* 18px — card title */
  /* THE deadline. Dropped from 20px once it moved into the stub: position
     now carries the emphasis that size used to, and 20px could not fit the
     worst-case date in a stub narrow enough to leave Japanese titles a
     readable measure. Still larger than everything else on the card. */
  --tcg-fs-deadline: 1.0625rem;  /* 17px — THE deadline. Nothing else on a
                                    card may use this size. */
  --tcg-fs-xl:       1.375rem;   /* 22px — section h2 */
  --tcg-fs-2xl:      1.75rem;    /* 28px — h1 mobile */
  --tcg-fs-3xl:      2.125rem;   /* 34px — h1 at 900px and above */

  /* Japanese needs more leading than Latin: dense glyphs, and no
     ascender/descender rhythm to carry the eye along the line. */
  --tcg-lh-tight:   1.4;   /* h1, h2, card titles */
  --tcg-lh-snug:    1.55;  /* chips, badges, buttons, dl, tables */
  --tcg-lh-base:    1.7;   /* board body text */
  --tcg-lh-article: 1.9;   /* long-form only — articles get air that the
                              information-dense board does not */

  /* Positive tracking helps Japanese on screen; it hurts large Latin. */
  --tcg-ls-tight:   -0.01em;  /* h1 only */
  --tcg-ls-base:     0.02em;  /* body */
  --tcg-ls-wide:     0.04em;  /* small labels, ad badge */
  --tcg-ls-eyebrow:  0.12em;  /* ALL-CAPS Latin eyebrow labels */

  /* =====================================================================
     SPACING — the board uses the tight end, articles the loose end
     ===================================================================== */
  --tcg-space-3xs: 2px;
  --tcg-space-2xs: 4px;
  --tcg-space-xs:  8px;
  --tcg-space-sm:  12px;
  --tcg-space-md:  16px;
  --tcg-space-lg:  24px;
  --tcg-space-xl:  32px;
  --tcg-space-2xl: 48px;
  --tcg-space-3xl: 64px;

  /* =====================================================================
     SHAPE — borders do the work, so shadows stay minimal.
     Cheaper to paint, and far better behaved in dark mode.
     ===================================================================== */
  --tcg-radius-sm:   4px;    /* badges */
  --tcg-radius-md:   8px;    /* cards */
  --tcg-radius-lg:   12px;   /* panels, sheets */
  --tcg-radius-pill: 999px;

  --tcg-shadow-card:    0 1px 2px rgba(16, 19, 25, .05);
  --tcg-shadow-sticky:  0 2px 8px rgba(16, 19, 25, .10);
  --tcg-shadow-overlay: 0 8px 32px rgba(16, 19, 25, .24);

  /* =====================================================================
     LAYOUT
     Breakpoint pixel values are hard-coded in the stylesheets, because
     custom properties do not work inside @media conditions. They are
     listed here so they cannot drift silently:

         600px   chip groups 2-up, deadline strip on one line
         900px   controls inline rather than sheet, card interior splits
        1200px   right rail appears

     A 1120px-wide entry card is unreadable, so the list is capped well
     below the shell width and the rail sits beside it.
     ===================================================================== */
  /* Width of the ticket stub (the deadline panel) at >=600px.
     Sized from the WORST case, not the common one: a two-digit month and
     day plus a weekday in parens (12/25(水)), and the year-crossing form
     (2027/1/5(火)). At 92px the closing paren was wrapping to a second
     line. Verified by measuring rendered text width, not by eye. */
  --tcg-stub-w:      118px;

  /* ONE measure for the whole site: page content, site header, site footer.
     Everything shares a left edge because everything uses this.

     840 rather than a narrower prose figure because the header's contents
     need 774px naturally (logo + nav + theme button), and a header that
     cannot fit its own cap is how the nav ends up wrapping on Windows,
     whose Yu Gothic metrics run wider than a Mac's. ~52 JP chars/line.

     Measured, not guessed: widening the board 760 -> 1120 gave a 1% shorter
     list and no change in median card height, because card height comes
     from its fixed rows rather than from text wrapping. So width past this
     buys nothing and costs line length. */
  --tcg-width-content: 840px;
  --tcg-width-shell:  1120px;  /* .alignwide / .tcg-wide bound only */

  /* Side ad rails. 160x600 is the standard skyscraper; 300x600 would need a
     ~1530px viewport to fit beside an 840px column, which is too rare to
     design for. The rails appear only above --tcg-bp-siderail; the content
     column is never narrowed to make room for them. */
  --tcg-width-sky:     160px;

  /* 広告ラベルの文言. Settable because 景表法 requires the ad to be
     identifiable as an ad, not one specific string — 広告 / PR / スポンサード
     all satisfy it, and networks ask for different wording. At port time
     PHP emits one inline :root declaration from the setting.

     NOT a way to remove the label: `.tcg-adslot--nolabel` exists only for
     slots with nothing in them, and affiliate link badges do not read this
     at all — their text lives in the HTML. */
  --tcg-ad-label: "広告";

  --tcg-z-sticky:  100;
  --tcg-z-header:  200;
  --tcg-z-overlay: 300;

  --tcg-dur-fast: 120ms;
  --tcg-dur-med:  240ms;
  --tcg-ease:     cubic-bezier(.2, .6, .3, 1);
}

/* ==========================================================================
   DARK MODE
   Re-binds the SAME token names. Guarded with :not([data-theme="light"]) so
   an explicit light choice can win, and repeated under [data-theme="dark"]
   so an explicit dark choice wins in the other direction.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --tcg-color-bg:             #0f1216;
    --tcg-color-surface:        #171b21;
    --tcg-color-surface-2:      #20262e;
    --tcg-color-surface-sunken: #0b0e12;
    --tcg-color-border:         #2b323c;
    --tcg-color-border-strong:  #3d4652;
    --tcg-color-text:           #e8ecf1;
    --tcg-color-text-muted:     #a3adba;
    --tcg-color-text-faint:     #7c8794;
    --tcg-color-text-invert:    #0f1216;

    --tcg-color-brand:          #6fa6f0;
    --tcg-color-brand-strong:   #93bdf7;
    --tcg-color-brand-soft:     #16233a;
    --tcg-color-brand-contrast: #0b1220;

    --tcg-color-open-fg:     #5fd08a;
    --tcg-color-open-bg:     #0f2b1c;
    --tcg-color-open-bd:     #2c6543;

    --tcg-color-upcoming-fg: #63c6d8;
    --tcg-color-upcoming-bg: #0c272d;
    --tcg-color-upcoming-bd: #2b5a64;

    --tcg-color-waiting-fg:  #e8b661;
    --tcg-color-waiting-bg:  #2e230d;
    --tcg-color-waiting-bd:  #63512a;

    --tcg-color-ended-fg:    #a3adba;
    --tcg-color-ended-bg:    #20262e;
    --tcg-color-ended-bd:    #39414c;

    --tcg-color-urgent-fg:   #ff8b8f;
    --tcg-color-urgent-bg:   #331416;
    --tcg-color-urgent-bd:   #6b2b2e;

    --tcg-color-ad-bg:       #4a525f;
    --tcg-color-ad-fg:       #ffffff;
    --tcg-color-ad-bd:       #5c6675;

    --tcg-color-star-on:     #f0b83a;
    --tcg-color-star-off:    #3d4652;
    --tcg-color-focus:       #7db2ff;

    /* A solid yellow marker on a dark background is unreadable, so the
       highlighter becomes a low-alpha wash instead of an opaque fill. */
    --tcg-color-marker-yellow: rgba(255, 226, 87, .26);
    --tcg-color-marker-pink:   rgba(255, 150, 190, .26);

    --tcg-color-point-bg: #10202f;  --tcg-color-point-bd: #3f6f9e;
    --tcg-color-warn-bg:  #2a1f0d;  --tcg-color-warn-bd:  #9b6f28;
    --tcg-color-sum-bg:   #142214;  --tcg-color-sum-bd:   #4d7a3f;
    --tcg-color-check-bg: #1c1830;  --tcg-color-check-bd: #6b5aa0;

    --tcg-color-balloon-bg: #232a33;
    --tcg-color-backdrop:   rgba(0, 0, 0, .66);

    --tcg-shadow-card:    0 1px 2px rgba(0, 0, 0, .40);
    --tcg-shadow-sticky:  0 2px 8px rgba(0, 0, 0, .50);
    --tcg-shadow-overlay: 0 8px 32px rgba(0, 0, 0, .64);
  }
}

/* Explicit dark choice wins regardless of the system setting. Values are
   duplicated rather than shared because CSS cannot alias a whole block. */
/* color-scheme has to follow the EXPLICIT choice, not just the OS.

   Without these two lines the palette flips but native controls do not:
   with the OS in dark mode and the site forced to light, `color-scheme:
   light dark` still tells the browser "either is fine", so it keeps
   painting checkboxes, radio buttons, select menus and scrollbars dark.
   The result is a black-filled checkbox sitting on a white card — which is
   exactly the bug this fixes. Custom CSS cannot reach those internals;
   color-scheme is the only lever. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

:root[data-theme="dark"] {
  --tcg-color-bg:             #0f1216;
  --tcg-color-surface:        #171b21;
  --tcg-color-surface-2:      #20262e;
  --tcg-color-surface-sunken: #0b0e12;
  --tcg-color-border:         #2b323c;
  --tcg-color-border-strong:  #3d4652;
  --tcg-color-text:           #e8ecf1;
  --tcg-color-text-muted:     #a3adba;
  --tcg-color-text-faint:     #7c8794;
  --tcg-color-text-invert:    #0f1216;

  --tcg-color-brand:          #6fa6f0;
  --tcg-color-brand-strong:   #93bdf7;
  --tcg-color-brand-soft:     #16233a;
  --tcg-color-brand-contrast: #0b1220;

  --tcg-color-open-fg:     #5fd08a;
  --tcg-color-open-bg:     #0f2b1c;
  --tcg-color-open-bd:     #2c6543;

  --tcg-color-upcoming-fg: #63c6d8;
  --tcg-color-upcoming-bg: #0c272d;
  --tcg-color-upcoming-bd: #2b5a64;

  --tcg-color-waiting-fg:  #e8b661;
  --tcg-color-waiting-bg:  #2e230d;
  --tcg-color-waiting-bd:  #63512a;

  --tcg-color-ended-fg:    #a3adba;
  --tcg-color-ended-bg:    #20262e;
  --tcg-color-ended-bd:    #39414c;

  --tcg-color-urgent-fg:   #ff8b8f;
  --tcg-color-urgent-bg:   #331416;
  --tcg-color-urgent-bd:   #6b2b2e;

  --tcg-color-ad-bg:       #4a525f;
  --tcg-color-ad-fg:       #ffffff;
  --tcg-color-ad-bd:       #5c6675;

  --tcg-color-star-on:     #f0b83a;
  --tcg-color-star-off:    #3d4652;
  --tcg-color-focus:       #7db2ff;

  --tcg-color-marker-yellow: rgba(255, 226, 87, .26);
  --tcg-color-marker-pink:   rgba(255, 150, 190, .26);

  --tcg-color-point-bg: #10202f;  --tcg-color-point-bd: #3f6f9e;
  --tcg-color-warn-bg:  #2a1f0d;  --tcg-color-warn-bd:  #9b6f28;
  --tcg-color-sum-bg:   #142214;  --tcg-color-sum-bd:   #4d7a3f;
  --tcg-color-check-bg: #1c1830;  --tcg-color-check-bd: #6b5aa0;

  --tcg-color-balloon-bg: #232a33;
  --tcg-color-backdrop:   rgba(0, 0, 0, .66);

  --tcg-shadow-card:    0 1px 2px rgba(0, 0, 0, .40);
  --tcg-shadow-sticky:  0 2px 8px rgba(0, 0, 0, .50);
  --tcg-shadow-overlay: 0 8px 32px rgba(0, 0, 0, .64);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --tcg-dur-fast: 0ms;
    --tcg-dur-med:  0ms;
  }
}

/* ==========================================================================
   theme.json MAPPING
   --------------------------------------------------------------------------
   At port time, replace the :root block above with aliases onto these.
   Nothing else in assets/css/ changes.

   --tcg-space-xs .. 3xl   settings.spacing.spacingSizes[]  slugs 20,30,40,50,60,70,80
                           -> var(--wp--preset--spacing--50)
   --tcg-color-*           settings.color.palette[]         slug e.g. "brand"
                           -> var(--wp--preset--color--brand)
   --tcg-fs-*              settings.typography.fontSizes[]  slugs sm,base,lg,xl,2xl
                           -> var(--wp--preset--font-size--lg)
   --tcg-font-sans         settings.typography.fontFamilies[] slug "sans"
                           -> var(--wp--preset--font-family--sans)
   --tcg-width-content     settings.layout.contentSize
   --tcg-width-shell       settings.layout.wideSize
   --tcg-lh-*, --tcg-ls-*,
   radii, shadows, z, dur  settings.custom.*
                           -> var(--wp--custom--...)

   Note contentSize = prose (720px) and wideSize = shell (1120px): that is
   what makes .alignwide behave sensibly inside articles for free.

   Only the LIGHT palette goes into theme.json. Dark stays here as a
   prefers-color-scheme block — see the note at the top of this file.
   ========================================================================== */
