/* ═══════════════════════════════════════════════════════════════
   XODE — THE LIGHT THEME

   Dark is the default and stays the default. This file does nothing at
   all until <html> carries data-theme="light".

   ── HOW IT WORKS ─────────────────────────────────────────────────
   The site is already written against tokens — 760 var() references
   across the public stylesheets — so the theme is mostly a matter of
   redefining them. Two idioms could not be expressed as tokens and
   have been given channel variables instead:

     --fg-rgb      the "raised surface" idiom. rgba(255,255,255,.06)
                   appears about a hundred times with forty different
                   alphas: a hairline, a hover, a faint panel. All of
                   them mean "a little of the foreground colour", so
                   they are now rgba(var(--fg-rgb), α) and the alpha is
                   left exactly as it was. On dark that is white; on
                   light it is the ink colour, and every one of those
                   forty values inverts correctly without being
                   listed.

     --shadow-rgb  a black shadow at .45 is right on near-black and far
                   too heavy on cream. A warm mid-grey at the same
                   alpha is what a shadow on paper looks like.

   ── THE DARK ISLANDS ─────────────────────────────────────────────
   Much of this site is pictures OF dark websites: the showcase minis,
   the template thumbnails, the Great Wall cards. Those are somebody
   else's dark portfolio being depicted, and they stay dark on a light
   page — the same way a photograph of a night sky does not brighten
   when you turn the lights on.

   Because custom properties inherit, that needs no per-declaration
   work: the dark values are re-declared on those subtree roots, and
   everything inside them — tokens and rgba(var(--fg-rgb)) alike —
   resolves back to the dark palette.

   ── THE THREE PALETTES ───────────────────────────────────────────
   Cream is the default; the other two are one attribute away. Every
   pair below was checked against WCAG rather than eyeballed, and the
   numbers are in THEME-2026-09-09.md.
   ═══════════════════════════════════════════════════════════════ */

/* :root[data-theme] rather than plain [data-theme] so this outranks
   every :root in the four stylesheets that also define these tokens,
   whatever order they happen to load in. */

/* ─────────────────────────────────────────────────────────────
   A — CREAM.  Warm neutral paper, the brand violet kept as the
   hero. The default.
   ───────────────────────────────────────────────────────────── */
:root[data-theme="light"] {
  /* Paper, not sand. The first pass sat at #F7F3EA, which is far
     enough into beige to look like an old page rather than a light
     one — and every surface above it inherited that dullness. */
  --bg-0: #FCFAF5;
  --bg-1: #FFFEFB;
  --bg-2: #FFFFFF;
  --bg-3: #F6F1E7;
  --bg-4: #EFE9DC;
  --border-1: #EBE4D6;
  --border-2: #D8CFBB;

  --text-0: #171410;
  --text-1: #3A342A;
  --text-2: #635B4C;
  --text-3: #6F685C;

  /* VIVID. These fill the buttons, draw the borders, light the glows
     and run through the gradient, and they are the brand — the exact
     values the dark theme uses. Only the ink below is deepened, and
     only because a 3.4:1 word cannot be read. */
  --violet: #7C5CFF;
  --violet-solid: #7C5CFF;
  --violet-dim: #5B42C9;
  --violet-glow: rgba(124, 92, 255, 0.20);
  --amber: #FFB454;
  --amber-dim: #D9962F;
  --amber-glow: rgba(255, 180, 84, 0.22);

  --violet-ink: #5B3FD6;
  --amber-ink: #9A6207;
  --violet-soft: #5B3FD6;

  --success: #1E8A4C;
  --danger: #C2352F;

  --ink-mix: 58%;
  --ink-with: #171410;

  --fg-rgb: 23, 20, 16;
  --shadow-rgb: 122, 104, 74;

  /* The full ramp, kept. The first pass took it to a brown that was
     readable and lifeless; this keeps the violet-to-warm falloff the
     dark theme has and lands the stops where large display type still
     clears 3:1 on paper. */
  --grad: linear-gradient(96deg, #7C5CFF 0%, #E9497F 58%, #F0762A 100%);
  --grad-diag: linear-gradient(135deg, #7C5CFF 0%, #E9497F 58%, #F0762A 100%);

  color-scheme: light;
}

/* ─────────────────────────────────────────────────────────────
   B — OAT.  The warmest of the three: sandy paper, ink-black
   type. Reads editorial rather than product.
   ───────────────────────────────────────────────────────────── */
:root[data-theme="light"][data-light="oat"] {
  --bg-0: #F8F3E9;
  --bg-1: #FDFAF4;
  --bg-2: #FFFFFF;
  --bg-3: #F0E9DA;
  --bg-4: #E6DDC9;
  --border-1: #E5DBC7;
  --border-2: #CDC2A8;

  --text-0: #1B1710;
  --text-1: #3E372B;
  --text-2: #665D4B;
  --text-3: #696256;

  --violet: #7C5CFF;
  --violet-solid: #7C5CFF;
  --violet-dim: #5B42C9;
  --violet-glow: rgba(124, 92, 255, 0.20);
  --amber: #FFB454;
  --amber-dim: #D9962F;
  --amber-glow: rgba(255, 180, 84, 0.24);

  --violet-ink: #5636CE;
  --amber-ink: #8F5A06;
  --violet-soft: #5636CE;

  --ink-mix: 56%;
  --ink-with: #1B1710;

  --fg-rgb: 27, 23, 16;
  --shadow-rgb: 118, 98, 66;

  --grad: linear-gradient(96deg, #7C5CFF 0%, #E9497F 58%, #EE7020 100%);
  --grad-diag: linear-gradient(135deg, #7C5CFF 0%, #E9497F 58%, #EE7020 100%);
}

/* ─────────────────────────────────────────────────────────────
   C — PORCELAIN.  The coolest: barely-warm off-white, neutral
   greys. Closest to the dark theme's own temperature.
   ───────────────────────────────────────────────────────────── */
:root[data-theme="light"][data-light="porcelain"] {
  --bg-0: #FAFAF9;
  --bg-1: #FDFDFD;
  --bg-2: #FFFFFF;
  --bg-3: #F1F1EF;
  --bg-4: #E8E8E6;
  --border-1: #E6E6E3;
  --border-2: #D0D0CC;

  --text-0: #111214;
  --text-1: #34363B;
  --text-2: #5D6067;
  --text-3: #686A70;

  --violet: #7C5CFF;
  --violet-solid: #7C5CFF;
  --violet-dim: #5B42C9;
  --violet-glow: rgba(124, 92, 255, 0.20);
  --amber: #FFB454;
  --amber-dim: #D9962F;
  --amber-glow: rgba(255, 180, 84, 0.22);

  --violet-ink: #5B3FD6;
  --amber-ink: #8E6110;
  --violet-soft: #5B3FD6;

  --ink-mix: 58%;
  --ink-with: #111214;

  --fg-rgb: 17, 18, 20;
  --shadow-rgb: 82, 86, 96;

  --grad: linear-gradient(96deg, #7C5CFF 0%, #E9497F 58%, #F0762A 100%);
  --grad-diag: linear-gradient(135deg, #7C5CFF 0%, #E9497F 58%, #F0762A 100%);
}

/* ═══════════════════════════════════════════════════════════════
   THE DARK ISLANDS

   Every one of these is a depiction of a dark website — a showcase
   mini, a template thumbnail, a Great Wall card, the phone and browser
   mock-ups. Re-declaring the dark tokens on the root of each puts the
   whole subtree back on the dark palette, including the hundred
   rgba(var(--fg-rgb), α) surfaces inside them.
   ═══════════════════════════════════════════════════════════════ */
:root[data-theme="light"] .sc-card,
:root[data-theme="light"] .sc-feature,
:root[data-theme="light"] .ta,
:root[data-theme="light"] .gw-slide-art,
:root[data-theme="light"] .gw-card-art,
:root[data-theme="light"] .gl-frame,
:root[data-theme="light"] .gl-shot,
:root[data-theme="light"] .hm-shot,
:root[data-theme="light"] .hu-thumb,
:root[data-theme="light"] .wz-card,
:root[data-theme="light"] .wz-code,
:root[data-theme="light"] .wz-cell,
:root[data-theme="light"] .mini-browser,
:root[data-theme="light"] .sc-tag,
:root[data-theme="light"] .xed-twinkle,
:root[data-theme="light"] [data-dark-island] {
  --bg-0: #0B0C0F;
  --bg-1: #131419;
  --bg-2: #1A1C22;
  --bg-3: #22242C;
  --bg-4: #2A2D36;
  --border-1: #2B2E37;
  --border-2: #383B46;
  --text-0: #F5F5F7;
  --text-1: #C7C9D1;
  --text-2: #8B8D98;
  --text-3: #5A5C66;
  --violet: #7C5CFF;
  --violet-solid: #7C5CFF;
  --fg-rgb: 255, 255, 255;
  --shadow-rgb: 0, 0, 0;
  /* Back to the no-op mix as well, or a badge inside one of these
     dark mock-ups would have its accent darkened for a light page it
     is not actually sitting on. */
  --ink-mix: 100%;
  --ink-with: #FFFFFF;
  --violet-ink: #7C5CFF;
  --amber-ink: #FFB454;
  --violet-soft: #C9BCFF;
  color-scheme: dark;
}

/* ═══════════════════════════════════════════════════════════════
   WHAT TOKENS COULD NOT SAY

   A short list on purpose. Anything long here is a sign the site
   should have been using a token in the first place.
   ═══════════════════════════════════════════════════════════════ */

/* The page itself. body takes --bg-0 already; html does not, and a
   short page shows the html background under the footer. */
:root[data-theme="light"] { background: var(--bg-0); }

/* A dark theme can leave an image alone. On cream, a screenshot with a
   near-black ground floats as a hole in the page unless something
   holds it — so pictures get the same hairline every other surface
   has. Not a filter: nothing here alters anybody's artwork. */
:root[data-theme="light"] .hm-card img,
:root[data-theme="light"] .pg-card img {
  border-radius: inherit;
}

/* The nav is a translucent bar over whatever scrolls beneath it. Its
   blur tint has to come from the page, not from black. */
:root[data-theme="light"] .nav {
  background: rgba(var(--fg-rgb), 0.04);
  border-bottom-color: var(--border-1);
}

/* Selection was white-on-violet by inheritance from the dark theme. */
:root[data-theme="light"] ::selection {
  background: var(--violet-glow);
  color: var(--text-0);
}

/* ── THE MARK ─────────────────────────────────────────────────────
   The logo is supplied as two files: the letterforms in white and the
   same letterforms in black, both on transparency. White is what the
   pages carry, because the dark theme is the default; on cream it
   would be a blank space, so the light theme points the same element
   at the black file.

   Swapping the src rather than filtering it matters. invert() would
   also produce black letterforms, but it would be this stylesheet
   redrawing supplied artwork — and the day the mark stops being pure
   white, invert() stops telling the truth. This is the other file, as
   it was given.

   The path is relative to THIS stylesheet, not to the page, so the one
   rule is correct from index.html and from pages/ alike — which is
   more than the markup can say, since it needs ../ on one and not the
   other. */
:root[data-theme="light"] .xode-mark {
  content: url("../assets/icon/xode-logo-dark.png");
}

/* …except on a dark island. Those keep their dark tokens on a light
   page — a screenshot, a mock-up, a preview of somebody's published
   work — so a mark inside one is still standing on near-black. */
:root[data-theme="light"] [data-dark-island] .xode-mark {
  content: url("../assets/icon/xode-logo.png");
}

/* ─────────────────────────────────────────────────────────────
   D — CANVAS.  Pure white, near-black ink, the brand violet taken a
   step deeper so it reads as ink on white. Since the Canvas redesign
   this is the site's only look: the boot snippet in every public
   page's <head> sets data-theme="light" data-light="canvas" before the
   first paint (tools/theme-boot.js). Nobody chooses it; there is no
   switch. styles/canvas.css carries what a palette cannot say.
   ───────────────────────────────────────────────────────────── */
:root[data-theme="light"][data-light="canvas"] {
  --bg-0: #FFFFFF;
  --bg-1: #F7F7FA;
  --bg-2: #FFFFFF;
  --bg-3: #F2F2F6;
  --bg-4: #E9E9EF;
  --border-1: #ECECF1;
  --border-2: #DCDCE4;

  --text-0: #0B0B0F;
  --text-1: #2A2A33;
  --text-2: #55555F;
  --text-3: #6B6B78;

  --violet: #6D4AFF;
  --violet-solid: #6D4AFF;
  --violet-dim: #5534E0;
  --violet-glow: rgba(109, 74, 255, 0.18);
  --amber: #FFB454;
  --amber-dim: #D9962F;
  --amber-glow: rgba(255, 180, 84, 0.22);

  --violet-ink: #5534E0;
  --amber-ink: #9A6207;
  --violet-soft: #5534E0;

  --success: #15803D;
  --danger: #C2352F;

  --ink-mix: 58%;
  --ink-with: #0B0B0F;

  --fg-rgb: 11, 11, 15;
  --shadow-rgb: 109, 74, 255;

  --grad: linear-gradient(96deg, #6D4AFF 0%, #C04CF5 52%, #FF5A8A 100%);
  --grad-diag: linear-gradient(135deg, #6D4AFF 0%, #C04CF5 52%, #FF5A8A 100%);

  --font-display: 'Inter Tight', 'Inter', sans-serif;

  color-scheme: light;
}
