/* ═══════════════════════════════════════════════════════════════════════════
   THEME — this is your file, José.

   Every color, size and speed the board uses is a variable in here. Change a
   value, save, press F5 in Chrome. Nothing else needs touching, and you cannot
   break the board from this file — the worst case is that it looks wrong and
   you undo it.

   The rule that makes this safe: board.css and board.js never contain a color.
   They only ever refer to the names below. So if a color exists, it is here.

   Rebranded 2026-08-23 (item 9/11): the old palette was a near-black,
   olive-green-accented, heavily-monospaced dark theme that read as a hacker
   terminal rather than a product — that is what "the Matrix theme" meant.
   This one keeps the same variable names (nothing outside this file changed)
   but swaps the palette for a deep indigo ground with a violet brand accent,
   and gives buttons real fill instead of a border sitting on the panel
   behind them (see --ui-btn below, and repertoire.css / settings.css, which
   were the two places still painting a control the same colour as its own
   background). The chessboard's own square colours are a separate,
   independently-selectable choice (Settings → Board) and were left alone —
   this is about the app's chrome, not the board.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── SCREEN SIZE ────────────────────────────────────────────────────────────
   How much bigger the whole app is drawn on a big monitor. Added 2026-09-14.

   Everything in the app — text, spacing, panels, the board — is measured in
   rem, and 1rem is the size of the root font set just below. So growing that
   one number grows the whole page together, the way zooming would, instead of
   leaving laptop-sized text floating in an ocean of empty screen.

   On a window up to --ui-scale-start wide, nothing changes: 1rem is 16px and
   every size is exactly what it was. Past it, the page grows steadily until it
   reaches --ui-scale-max. With the values below:

     1440px wide and under   laptop size    (text 14px)
     1920px (a 1080p screen) 1.10×          (text 15.4px)
     2560px (a 1440p screen) 1.23×          (text 17.3px)
     3840px (a 4K screen)    1.50×          (text 21px) — the cap

   The three knobs:
     --ui-scale-start  the window width where growing begins
     --ui-scale-rate   how many px of extra width add 1px to the root font.
                       Smaller grows faster: 200 reaches the cap around 3040px.
     --ui-scale-max    the cap, as a percentage of normal size

   Browser zoom (Ctrl + scroll) still works on top of this, and it is the way
   to make things bigger or smaller by hand. On a monitor wide enough to be
   scaling, zoom has a little less effect than on a laptop: zooming makes the
   page's width smaller in CSS terms, so the automatic part gives some of it
   back. The "100% +" at the front of the formula is what keeps zoom working at
   all — do not remove it; a formula made only of vw would ignore zoom entirely.

   The percentages are of the BROWSER's own text size, so someone who set their
   browser text larger still gets it, on every screen.

   Media queries are not affected: they measure the window in px, which does
   not change when the page scales. */
:root {
  --ui-scale-start: 1440px;
  --ui-scale-rate: 300;
  --ui-scale-max: 150%;
}

html {
  font-size: clamp(100%, calc(100% + (100vw - var(--ui-scale-start)) / var(--ui-scale-rate)), var(--ui-scale-max));
}

/* ── TOUCH SCREENS ──────────────────────────────────────────────────────────
   Phones and tablets, where a finger is the pointer. Added 2026-09-14.

   `pointer: coarse` is true for a touchscreen and false for a mouse or a
   trackpad, so a laptop never sees any of this — it is exactly as it was.

   --touch-target is how tall the small controls become: 2.75rem is 44px, the
   size Apple and Google both recommend for something a thumb has to hit. The
   folding "Goal / Schedule / Backups" rows were 21px tall and the text boxes
   21px, which is a tap that lands on the wrong thing half the time.

   Text in a box is at least 16px on a touchscreen for a different reason:
   Safari on an iPhone ZOOMS THE WHOLE PAGE when you tap into a box whose text
   is smaller than that, and leaves you zoomed in. The app's boxes were 12px,
   so every search and every form would have jumped. */
:root {
  --touch-target: 2.75rem;
}

/* ── SMALLEST TEXT ON A PHONE ───────────────────────────────────────────────
   The app's smallest text — the uppercase section labels ("ACCOUNT", "PLANS"),
   weekday letters, table headers, tags — is 10–11px, a compact style that
   reads fine on a laptop and is hard on a phone. Added 2026-09-14.

   Every one of those sizes is written as max(<its own size>, var(--text-min)).
   --text-min is 0 everywhere, so max() just gives back the size it was given
   and nothing changes; on a window 700px wide or narrower it is 0.75rem (12px),
   and anything smaller comes up to that. Labels keep their weight, spacing and
   capitals, just a little larger.

   Change 0.75rem below to move the floor. The 700px is a window width and has
   to be typed as a number: a media query cannot read a variable. */
:root {
  --text-min: 0px;
}
@media (max-width: 700px) {
  :root { --text-min: 0.75rem; }
}
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
  select,
  textarea {
    font-size: max(1rem, 16px);
    min-height: var(--touch-target);
  }
  /* Padding, not display:flex — a flex summary loses its ▶ marker, which is the
     only thing telling you the row opens. 21px of text plus this is about 44. */
  summary {
    padding-block: calc((var(--touch-target) - 1.3rem) / 2);
  }
  /* flex: none as well — in a flex row (Settings → Opening databases) the box
     was squeezed back to 13px wide by its own line of text. */
  input[type="checkbox"],
  input[type="radio"] {
    width: 1.25rem;
    height: 1.25rem;
    flex: none;
  }
  /* Buttons are deliberately NOT forced taller here: the weekday picker, the
     calendar's half-hour slots and the Both/White/Black switch are rows of small
     buttons laid out to fit, and one blanket min-height would break all three. */
}

:root {
  /* ── BOARD SQUARES ─────────────────────────────────────────────────────
     The two square colors — the classic brown, and the default.
     The other palettes are at the BOTTOM of this file and are selectable from
     Settings → Board, so you no longer have to copy one up here. Change these
     two values to change what "brown" means. */
  --sq-light: #f0d9b5;
  --sq-dark: #b58863;

  /* Coordinate letters and numbers printed in the square corners.
     They sit ON a square, so each needs to contrast with the OTHER color. */
  --coord-on-light: #b58863;
  --coord-on-dark: #f0d9b5;
  /* cqw = percent of the BOARD's width, so coordinates stay proportional at any
     board size. Do not change this to % — a percentage font-size resolves
     against the page font instead and the coordinates vanish.
     The max() is a floor, added 2026-09-14: on a phone the board is about 330px
     and 2.1% of that is a 7px "8" nobody can read. --coord-min is the smallest
     they get; on any board wider than about 380px the proportional size is
     already bigger, so it only ever changes phone-sized boards. */
  --coord-min: 0.5rem;
  --coord-size: max(2.1cqw, var(--coord-min));
  --coord-weight: 700;

  /* ── PIECES ─────────────────────────────────────────────────────────────
     Used by the built-in sets (`staunton`, `flat`), which are silhouettes
     colored from here — and by a file in web/board/pieces/<set>/ that did not
     name a side, which is treated the same way. A file that DOES name its side
     (white-pawn.png) is an <img>, carries its own colors, and ignores all of
     this — that is the trade for using artwork of your own. */
  --piece-light: #ffffff;
  --piece-dark: #2e2b29;
  --piece-outline: #16150f;
  --piece-outline-width: 1.1;   /* in the 45x45 piece viewBox, not pixels */
  --piece-scale: 0.92;          /* 1 = piece fills the square edge to edge */
  --piece-mask-edge: 1px;       /* the outline on a folder silhouette, in px */

  /* ── HIGHLIGHTS ─────────────────────────────────────────────────────────
     Painted over the square, so they want to be semi-transparent. */
  --hl-last: rgba(155, 199, 0, 0.41);    /* the move just played */
  --hl-selected: rgba(20, 85, 30, 0.5);  /* the piece you picked up */
  --hl-check: radial-gradient(ellipse at center,
                rgba(255, 0, 0, 0.9) 0%, rgba(231, 0, 0, 0.8) 25%,
                rgba(169, 0, 0, 0) 89%);
  --hl-premove: rgba(20, 30, 85, 0.45);  /* a move queued before it is your turn */
  --hl-target: rgba(20, 85, 30, 0.28);   /* squares you may move to */
  --hl-target-size: 24%;                 /* the dot; 100% would fill the square */
  --hl-hover: rgba(255, 255, 255, 0.65); /* square a dragged piece is over */
  --hl-hover-width: 4px;

  /* ── DRAGGING ───────────────────────────────────────────────────────────
     How a piece looks while it is held. --drag-scale 1 turns the lift off. */
  --drag-scale: 1.12;
  --drag-shadow-y: 4px;
  --drag-shadow-blur: 8px;

  /* ── ARROWS AND CIRCLES ─────────────────────────────────────────────────
     Referred to by name from JS: board.arrow('e2','e4','green') */
  --arrow-green: rgba(21, 120, 27, 0.8);
  --arrow-red: rgba(136, 21, 21, 0.8);
  --arrow-blue: rgba(0, 108, 178, 0.8);
  --arrow-yellow: rgba(197, 158, 0, 0.8);

  /* ── MOTION ─────────────────────────────────────────────────────────────
     Set --anim-move to 0s to turn animation off entirely. */
  --anim-move: 0.18s;
  --anim-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --anim-fade: 0.16s;

  /* ── FRAME ──────────────────────────────────────────────────────────────
     The border around the board. --board-radius 0 gives hard corners. */
  --board-radius: 4px;
  --board-shadow: 0 2px 14px rgba(0, 0, 0, 0.35);
  --board-border: none;   /* e.g. 6px solid #3b2f24 for a wooden edge */

  /* ── BOARD SIZE ─────────────────────────────────────────────────────────
     The starting width. Drag the grip at the board's bottom-right corner to
     change it live; that overrides this value and remembers your choice.
     --board-min / --board-max are the limits the grip will not go past. */
  /* How much vertical room the learning screen needs for everything that is
     NOT the board. The board is capped at 100vh minus this, so lowering it
     makes the board bigger on a short window.

     It was 168px until 2026-08-31, when the header, the prompt, the buttons
     and the progress bar all moved into the column BESIDE the board. Nothing
     is above or below it any more, so this is only the page's own padding —
     which is why the board grew by most of a hundred and thirty pixels for
     free. Raise it if you want air around the board. */
  --learn-chrome: 2.5rem;

  --board-size: 40rem;
  --board-min: 15rem;
  /* 87.5rem since 2026-09-14 (it was 900px, then 56.25rem). On a 4K screen the
     learning board stopped at 1350px with 800px of height still free under it;
     the Build screen already allowed 87.5rem. On a laptop the window's height
     runs out long before either limit, so this changes nothing there. */
  --board-max: 87.5rem;

  /* ── APP CHROME ─────────────────────────────────────────────────────────
     Everything that is the app's own UI, not the board: page background,
     panels, text, buttons. A deep indigo ground with a violet brand accent —
     deliberately not black-and-green. */
  --ui-bg: #12131c;
  --ui-panel: #1b1d2a;
  --ui-line: #2f3244;
  --ui-text: #eef0f7;
  --ui-dim: #949ab0;
  --ui-accent: #7c6cf2;
  --ui-accent-text: #ffffff;

  /* The logo, as an image the theme chooses. `content:` on an <img> replaces
     what it renders, so the markup names ONE file and the stylesheet decides
     which of the two is actually shown — light on a light page, and the one
     with the pawn inverted on a dark one. The pawn is black; on #12131c the
     unaltered mark is a hole in a purple cloud. See tools/make-logo.js. */
  --logo-mark: url("/assets/logo-192-dark.png");

  /* Pro. Gold, because that is what José asked for and because it is the one
     colour in this palette that is not already carrying a meaning — violet is
     the accent, green is a right answer, red is a wrong one. It marks a
     feature that exists and is paid for, never a warning. See role.css. */
  --pro-gold: #e3b341;
  --pro-gold-dim: #6b5316;
  --pro-gold-text: #1b1405;
  /* "+ Tactic" and "+ Endgame" on the Repertoire screen, 2026-09-15. Gold like
     the Gold pieces, José's choice. Its own pair rather than --pro-gold,
     because that one means "this is a Pro feature" and these buttons are for
     everybody. --ui-gold-text is the text on it. */
  --ui-gold: #e3b341;
  --ui-gold-text: #1b1405;
  /* Controls: buttons, their hover, and the inside of a text box. A control
     needs real fill — a colour clearly lighter than the panel it sits on —
     or it reads as a border floating on the background rather than a
     pressable thing. (This was the "border-only buttons" complaint:
     repertoire.css and settings.css were painting a button the same colour
     as its own panel, so only the 1px outline was visible.) */
  --ui-btn: #262a3d;
  --ui-btn-hover: #333750;
  --ui-input-bg: #15161f;
  /* The backend status dot in the shell header. */
  --status-up: #3ecf8e;
  --status-down: #f0605a;
  --ui-radius: 0.5rem;
  --ui-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ui-mono: "Cascadia Code", "SF Mono", Consolas, monospace;

  /* ── REPERTOIRE ─────────────────────────────────────────────────────────
     The database tab: folders, variations, and the learning screen.

     The seven level colors run cold to warm, Difficult to Mastered. They are
     the fastest thing to read on a crowded list, so keep them distinguishable
     from each other rather than pretty in isolation. */
  --lvl-0: #f0605a;   /* Difficult */
  --lvl-1: #f2994a;
  --lvl-2: #f2c94c;
  --lvl-3: #4fd17c;
  --lvl-4: #2fc9c2;
  --lvl-5: #4fb6f2;
  --lvl-6: #9b7cf2;   /* Mastered */

  /* Which colour a variation is for. */
  --side-white: #eef0f7;
  --side-white-text: #14161f;
  --side-black: #2f3244;
  --side-black-text: #eef0f7;
  --side-both: #4fb6f2;
  --side-both-text: #0b1220;

  /* The learning screen's answers. Green means the move was right; red means
     try again; amber means the app had to play it for you. */
  --learn-right: #3ecf8e;
  --learn-wrong: #f0605a;
  --learn-shown: #f2a341;
  --learn-xp: #f2c94c;

  /* Due now is the only thing on the page allowed to shout. */
  --due-now: #f0605a;
  --due-later: #949ab0;
}

/* Respect the reader's motion preference. Leave this alone unless you have a
   reason — it is an accessibility setting, not a style choice. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --anim-move: 0s;
    --anim-fade: 0s;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   BOARD PALETTES

   Pick one in Settings → Board. Each block overrides only the square colors
   and the coordinates that sit on them; everything else above is untouched.

   To add your own: copy a block, give it a new name in the brackets, and add
   one line to BOARD_THEMES in appearance.js so it appears in the picker.

   The coordinate rule is the only thing to be careful about — a coordinate is
   printed ON a square, so it takes the colour of the OTHER square to stay
   readable.
   ══════════════════════════════════════════════════════════════════════════ */

/* Brown is the default and is defined in :root above, so it needs no block. */

:root[data-board="blue"] {
  --sq-light: #dee3e6;
  --sq-dark: #8ca2ad;
  --coord-on-light: #8ca2ad;
  --coord-on-dark: #dee3e6;
}

:root[data-board="green"] {
  --sq-light: #ffffdd;
  --sq-dark: #86a666;
  --coord-on-light: #86a666;
  --coord-on-dark: #ffffdd;
}

:root[data-board="ivory"] {
  --sq-light: #efe3c8;
  --sq-dark: #8a6f47;
  --coord-on-light: #8a6f47;
  --coord-on-dark: #efe3c8;
  --piece-light: #f6efdd;
  --piece-dark: #2a2118;
  --piece-outline: #6b5220;
}

:root[data-board="gray"] {
  --sq-light: #dcdcdc;
  --sq-dark: #8f8f8f;
  --coord-on-light: #8f8f8f;
  --coord-on-dark: #dcdcdc;
}

:root[data-board="slate"] {
  --sq-light: #6c6a68;
  --sq-dark: #3f3d3b;
  --coord-on-light: #3f3d3b;
  --coord-on-dark: #9a938a;
  --piece-light: #eeeae3;
  --piece-dark: #171514;
}

/* ══════════════════════════════════════════════════════════════════════════
   LIGHT THEME

   Everything above is the dark theme. This block is the light one, and it
   overrides ONLY the page chrome — the board keeps whatever palette is
   selected, because a board's colors are not a function of the room's lights.

   Settings → Appearance switches between them, and "Follow my system" tracks
   the OS. appearance.js writes data-theme onto <html>; nothing else changes.

   Every colour here is the counterpart of one above. If you add a variable up
   there and it needs to differ on light, add it here too — a missing one is
   not an error, it just stays dark and will look wrong on white.
   ══════════════════════════════════════════════════════════════════════════ */

:root[data-theme="light"] {
  /* Page chrome. A cool off-white rather than pure #fff: a full-brightness
     white page next to a brown board is glare, not contrast. */
  --ui-bg: #f5f6fb;
  --ui-panel: #ffffff;
  --ui-line: #dfe2ee;
  --ui-text: #181a24;
  --ui-dim: #5c6178;
  --ui-accent: #5b46e0;
  --ui-accent-text: #ffffff;
  /* The black pawn, which is the logo as drawn — it only needs the inverted
     treatment on a dark ground. */
  --logo-mark: url("/assets/logo-192.png");
  /* Darker on white: #e3b341 on a light panel is a highlighter, not a border. */
  --pro-gold: #a97b12;
  --pro-gold-dim: #f0dfb0;
  --pro-gold-text: #2b2007;
  /* A brighter gold than --pro-gold here, because this one is a FILL with dark
     text on it, not a border on white. */
  --ui-gold: #e0ab3a;
  --ui-gold-text: #1f1605;
  --ui-btn: #eef0f8;
  --ui-btn-hover: #e2e5f3;
  --ui-input-bg: #ffffff;
  --status-up: #1f9d68;
  --status-down: #d6453f;

  /* The level colours, darkened until each one passes as text on white. The
     dark-theme values are tuned for a near-black background and turn to pastel
     mush on this one. */
  --lvl-0: #d6453f;
  --lvl-1: #c17a1f;
  --lvl-2: #a68a16;
  --lvl-3: #1f9d68;
  --lvl-4: #17968f;
  --lvl-5: #1c7fc4;
  --lvl-6: #6a4fd6;

  --side-white: #ffffff;
  --side-white-text: #181a24;
  --side-black: #2a2d3d;
  --side-black-text: #f5f6fb;
  --side-both: #1c7fc4;
  --side-both-text: #ffffff;

  --learn-right: #1f9d68;
  --learn-wrong: #d6453f;
  --learn-shown: #b3701a;
  --learn-xp: #9c7c17;

  --due-now: #d6453f;
  --due-later: #5c6178;

  /* A shadow tuned for a dark page disappears on a light one. */
  --board-shadow: 0 2px 14px rgba(0, 0, 0, 0.18);
}

