/* ============================================================
   POMBLE — PLATFORM THEME
   The single source of truth for colour across the whole platform.
   Every screen and every game imports this and uses the variables —
   never hard-coded colours. Change a value here, it changes everywhere.

   Usage in any game/page:
     <link rel="stylesheet" href="platform-theme.css">
     body { background: var(--paper); color: var(--ink); }
   ============================================================ */

:root {
  /* ---- The page (Paperwhite) ---------------------------------
     A warm, low-glare e-reader page. This is THE platform
     background — the hub, every game, every screen sits on it. */
  --paper:    #F6F3EA;   /* platform background                  */
  --panel:    #FCFAF4;   /* cards, boards, raised surfaces       */
  --raised:   #FDFBF6;   /* the lightest surface: a puzzle cell, an
                            input - the things that must read as empty
                            and ready. NOT white: the founder's rule is
                            no white anywhere, and #FFFFFF has now gone
                            from the platform entirely. */

  /* ---- Ink & lines ------------------------------------------ */
  --ink:      #211E19;   /* primary text                          */
  --soft:     #57524A;   /* secondary text, labels                */
  --faint:    #645D4B;   /* hints, disabled, fine print.
                            WAS #A79E88, which measured 2.40:1 on the
                            page - well under the 4.5:1 minimum, on the
                            text most likely to be needed. Now 5.75:1. */
  --line:     #DDD3BC;   /* hairlines between things              */
  --line-2:   #C9BFA4;   /* where a border must actually hold a shape */

  /* ---- Lines you have to be able to SEE ----------------------
     A card's hairline can be delicate; a Sudoku grid line cannot.
     You have to follow it to play, so it is a separate job with a
     separate token and a measured floor. */
  --rule:        #B5A88A;   /* cell and tile edges           2.20:1 */
  --rule-strong: #8F8A72;   /* box dividers, board outline   3.25:1 */

  /* ---- Functional accents ------------------------------------
     Each colour has ONE fixed job across the whole platform, so
     children learn that colour means something. Never decorative,
     never a reward. */
  --sage:     #59784B;   /* correct · complete · in place         */
  --slate:    #42658A;   /* next step · current target            */
  --clay:     #A65D32;   /* letters · placed letter               */

  /* --sage and --clay were nudged 5% and 1% darker on 8 Aug 2026, same hue
     and saturation. Reason: pale text sat on both as a solid button fill, and
     at their old values that text measured 4.20:1 and 4.46:1 - under the 4.5
     minimum. Every other functional colour already cleared it. The shift is
     4-6 points per channel, invisible side by side, and it means ONE pale-ink
     token is safe on every solid in the platform instead of each game having
     to know which colours it may not write on. */
  --blue:     #3D6DA8;   /* numbers · chosen number               */

  /* ---- Game surfaces ----------------------------------------- */
  --covered:   #D8CDB0;  /* un-revealed square (e.g. Meadow grass)*/
  --covered-2: #D1C5A6;  /* alternate shade for a soft chequer    */
  --dug:       #FDFBF6;  /* revealed / cleared square (= --raised)*/

  /* ---- Number colours (grid games) ---------------------------
     Strong and distinct so a child can read them at a glance. */
  --n1: #2F6FB0;  --n2: #4C7A3A;  --n3: #B4552A;  --n4: #3B4F86;
  --n5: #8C3A3A;  --n6: #2F7C7C;  --n7: #4A463C;  --n8: #1F1E1A;

  /* ---- Shape & spacing --------------------------------------- */
  --r-xs: 4px;  --r-sm: 5px;  --r-md: 6px;  --r-lg: 8px;  --r-xl: 10px;
  --r-pill: 999px;
  --pad:  16px;
  --touch-min: 44px;     /* minimum touch target for small fingers */

  /* ---- Type --------------------------------------------------- */
  --font: "Segoe UI", Helvetica, Arial, sans-serif;
  --t-title: 19px;  --t-body: 14px;  --t-small: 12.5px;

  /* ---- Brand accent: TEAL -------------------------------------
     The fifth reserved colour (founder's choice July 2026, after
     the colour-in-learning research: cool blue-green aids attention
     and memory; the earlier warm accents are retired).
     Teal means "the brand speaking": wordmark, primary actions,
     where-you-are markers. Preferred form is THIN STROKES and fine
     marks, not heavy fills. Never inside a game; never takes a
     functional colour's job. */
  --accent:      #2C6E68;   /* teal — strokes, underlines, wordmark      */
  --accent-deep: #1F524D;   /* pressed states, gradient partner          */
  --accent-tint: rgba(44, 110, 104, 0.08);  /* highlighted panel wash    */
  --accent-hl:   rgba(44, 110, 104, 0.16);  /* marker-pen word highlight */
  --on-accent:   #F1F6F4;   /* text on solid teal                        */
  --accent-pale: #C9E3DF;   /* lit chips and pills - teal at low strength */

  /* ---- Highlighter: PERIWINKLE --------------------------------
     The sixth reserved colour (founder's choice July 2026): directs
     the eye — "look here". Help affordances, NEW tags, selected
     filter chips, fine strokes around boxes that need attention.
     Never marks errors, never fills large areas, never in games. */
  --hi:        #7B87C4;
  --hi-strong: #5F6BAE;                     /* strokes & text            */
  --hi-tint:   rgba(123, 135, 196, 0.14);   /* soft attention wash       */

  /* ---- Depth ---------------------------------------------------
     Soft, warm shadows — paper lifting off a desk, not material
     design. Use sparingly: cards, panels, the sticky header. */
  --shadow-sm: 0 1px 2px rgba(93,78,55,.07), 0 2px 6px rgba(93,78,55,.07);
  --shadow-md: 0 1px 2px rgba(93,78,55,.06), 0 6px 18px rgba(93,78,55,.12);
}

/* ---- Base ---------------------------------------------------- */
/* The warm wash: a pool of light at the top of the page falling
   away to slightly deeper paper at the edges — a lamp on a desk.
   Fixed so the light stays put while the page scrolls. */
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  background-color: var(--paper);
  background-image: radial-gradient(ellipse 120% 75% at 50% -8%,
    #FAF7EE 0%, #F8F5EC 36%, var(--paper) 60%, #EFEADA 100%);
  background-attachment: fixed;
  color: var(--ink);
}

/* ---- While a game is open, the chrome steps back ---------------
   Browsing furniture is not playing furniture: the genre bar and the
   main nav are for choosing a game, and the game's own sub-header
   already carries "‹ The shelf". So during play the wordmark shrinks
   and the browsing rows go, giving the board the room it needs. */
/* Inside the hub the instructions live in the card beside the game, so
   the game's own long explanation and footnote would be saying the same
   thing twice — and pushing the board off the bottom of the screen to
   do it. They stay in the page for screen readers, and leave the
   layout. */
body.in-hub .prompt, body.in-hub .hint {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
}

/* …and the spacing that was sized for a whole page of its own tightens
   up, because in the hub the game is a panel, not a page. */
body.in-hub main { padding-top: 4px; padding-bottom: 10px; }
body.in-hub .status { margin-bottom: 6px; }
body.in-hub .msg { margin-top: 8px; }
body.in-hub .again { margin-top: 8px; }

body.playing .qh-genres { display: none; }
body.playing .qh-nav { display: none; }
body.playing .qh-wordmark img { height: 32px; }
body.playing .qh-chrome .qh-bar { padding: 6px 24px; }
body.playing .qh-chrome { box-shadow: none; }

/* ---- Site chrome: header bar + horizontal nav ----------------- */
/* Every hub page uses this. The wordmark lives in the header; the
   nav row sits directly beneath it. Active nav = ink underline —
   "where you are" is information, not decoration. */
.qh-chrome {
  width: 100%; background: var(--panel); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 50; box-shadow: var(--shadow-sm);
}
.qh-chrome .qh-bar {
  max-width: 1020px; margin: 0 auto; padding: 8px 24px 6px;
  display: flex; align-items: center; gap: 18px;
}
.qh-wordmark {
  font-size: 17px; font-weight: 700; letter-spacing: 2.5px;
  color: var(--accent); margin: 0; flex: 1;
}
.qh-wordmark a { color: inherit; text-decoration: none; }
/* The Pomble logo — traced vector, true transparency, sized by its
   real artwork (research: 250–400px content width on desktop). */
/* 46px, to match the homepage header. It was 72px, which at this artwork's
   proportions is about 344px wide - it dominated every screen and made the
   app look like a different product from its own front door. */
.qh-wordmark img { height: 40px; display: block; }
@media (max-width: 820px) { .qh-wordmark img { height: 34px; } }
/* On a short screen the header must not eat the page — shrink the
   wordmark and the padding, but never the 44px nav touch targets. */
@media (max-height: 720px) {
  .qh-wordmark img { height: 32px; }
  .qh-chrome .qh-bar { padding: 6px 16px 2px; }
  .qh-nav { padding: 0 10px; }
}

/* ---- Genre bar: move between kinds of game from anywhere -------
   The pattern game hubs use — icon+label chips, horizontally
   scrollable as the categories grow. Selection wears periwinkle
   ("look here"); each chip carries its category's own muted hue. */
.qh-genres { width: 100%; background: var(--raised); border-bottom: 1px solid var(--line); }
.qh-genres .in {
  max-width: 1020px; margin: 0 auto; padding: 5px 16px;
  display: flex; gap: 8px; overflow-x: auto;
}
.qh-genre {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--line); background: var(--panel);
  border-radius: 22px; padding: 6px 14px; font-size: 13px; color: var(--soft);
  cursor: pointer; font-family: var(--font); white-space: nowrap;
  min-height: 38px; flex: none;
}
/* A finger needs 44px; a mouse pointer does not. Compact for desktop,
   full size the moment the device is touched. */
@media (pointer: coarse) { .qh-genre { min-height: 44px; padding: 8px 15px; } }
.qh-genre .tx { font: 700 9.5px var(--font); margin-right: 2px; }
.qh-genre svg, .qh-genre .tx { flex: none; }
.qh-genre.on { border: 1.5px solid var(--hi-strong); background: var(--hi-tint); color: var(--ink); font-weight: 600; }

/* ---- The user corner: friendlier greeting + language ---------- */
.qh-me { display: flex; align-items: center; gap: 10px; }
.qh-hi {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--line); background: var(--paper);
  border-radius: 22px; padding: 6px 14px 6px 7px; cursor: pointer;
  min-height: 44px; font-family: var(--font); text-align: left;
}
.qh-hi .face {
  width: 32px; height: 32px; border-radius: 6px; background: var(--panel);
  border: 1px solid var(--line); font: 650 15px/30px var(--font);
  text-align: center; position: relative; overflow: hidden; flex: none;
}
.qh-hi .face i { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; }
.qh-hi b { font-size: 14px; font-weight: 600; color: var(--ink); display: block; }
.qh-hi span { font-size: 11px; color: var(--faint); }
/* the person chip's little menu: switch player, or sign out */
.qh-who { position: relative; }
.qh-memenu { right: 0; min-width: 168px; }
.qh-memenu button { font-size: 14px; }
.qh-lang { position: relative; }
.qh-langbtn {
  border: 1px solid var(--line); background: var(--paper); border-radius: 8px;
  min-width: 48px; min-height: 44px; cursor: pointer; font-family: var(--font);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; padding: 5px 8px;
}
.qh-langmenu {
  position: absolute; right: 0; top: 50px; background: var(--raised);
  border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow-md);
  padding: 6px; min-width: 190px; display: none; z-index: 60;
}
.qh-langmenu.open { display: block; }
.qh-langmenu button {
  display: flex; gap: 9px; align-items: center; width: 100%; border: 0; background: none;
  font-family: var(--font); font-size: 13.5px; color: var(--ink);
  padding: 9px 10px; border-radius: 5px; cursor: pointer; text-align: left;
}
.qh-langmenu button:hover { background: var(--paper); }
.qh-langmenu .tick { margin-left: auto; color: var(--accent); font-weight: 700; }
.qh-langmenu .soon { color: var(--faint); }
.qh-langmenu .soon small { margin-left: auto; font-size: 10px; }
.qh-nav {
  max-width: 900px; margin: 0 auto; padding: 0 16px;
  display: flex; gap: 2px; overflow-x: auto;
}
.qh-nav a {
  padding: 10px 14px; color: var(--soft); text-decoration: none;
  font-size: 14px; white-space: nowrap; border-bottom: 2px solid transparent;
  min-height: 44px; display: flex; align-items: center;
}
.qh-nav a.on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.qh-nav a:active { background: var(--paper); }

/* ---- Shared components --------------------------------------- */
.qh-panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--pad);
  box-shadow: var(--shadow-sm);
}

/* primary action button — the brand speaking.
   Gradient toward the deep shade keeps cream text readable. */
.qh-primary {
  border: 1px solid var(--accent-deep);
  background: linear-gradient(160deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--on-accent);
  border-radius: 8px;
  padding: 12px 22px;
  font-size: 15px;
  font-family: var(--font);
  cursor: pointer;
  min-height: var(--touch-min);
  box-shadow: var(--shadow-sm);
}
.qh-primary:active { background: var(--accent-deep); border-color: var(--accent-deep); }

.qh-btn {
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--soft);
  border-radius: var(--r-md);
  padding: 8px 15px;
  font-size: var(--t-body);
  font-family: var(--font);
  cursor: pointer;
  min-height: var(--touch-min);
}
.qh-btn:active { background: var(--line); }

/* selected / active state */
.qh-btn.is-on {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

/* success message — the only "well done", quiet and plain */
.qh-done { color: var(--sage); font-weight: 600; }
/* calm end of round — never a punishment. Neutral by research:
   red-family hues signal failure below conscious awareness. */
.qh-end  { color: var(--soft); font-weight: 600; }

/* screen-reader-only text */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0,0,0,0);
}

/* ============================================================
   RULES
   1. No hard-coded colours in a game — use the variables above.
   2. Accents keep their fixed meaning everywhere. Don't reuse
      --sage for decoration; it means "correct".
   3. Nothing here rewards. No golds, no glitter, no celebration.
   ============================================================ */


/* ---- the nav, reworked 14 Aug 2026 ----
   Icons so it works before reading does; the grown-ups' room set apart on the
   right with a padlock, because separating it by position as well as by name
   is what stops three links reading as three similar things. */
.qh-nav a { display: inline-flex; align-items: center; gap: 7px; }
.qh-nav a svg { width: 16px; height: 16px; flex: none; }
.qh-nav a.apart { margin-left: auto; }
@media (max-width: 560px) {
  .qh-nav a span { display: none; }        /* the icons carry it when there is no room */
  .qh-nav a { padding: 9px 12px; }
  .qh-nav a.on span { display: inline; }   /* except where you are, which still says so */
}


/* The grown-ups door in the top bar. Quiet - it is not for the child - but
   reachable without reading the nav, which is what a parent arriving to
   change a setting actually needs. */
.qh-admin { display: inline-flex; align-items: center; gap: 7px; min-height: 44px;
  padding: 0 13px; border: 1px solid var(--line); background: var(--paper);
  border-radius: 8px; color: var(--soft); font-size: 13px; text-decoration: none; }
.qh-admin svg { width: 15px; height: 15px; }
.qh-admin:hover { border-color: var(--line-2); color: var(--ink); }
@media (max-width: 560px) { .qh-admin span { display: none; } .qh-admin { padding: 0 11px; } }
.qh-hi .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
