/* learn-v3.css — the learn index and the series pages.
 *
 * Versioned by filename because Hostinger edge-caches CSS for seven days, so a
 * change ships as learn-v4.css with every page repointed in the same commit.
 * Editing this file in place means a returning reader runs last week's copy for
 * a week.
 *
 * Three kinds of card share most of this:
 *   .mod.ser    a series on /learn.html
 *   .mod.done   a written module on a series page
 *   .mod.soon   a module that is not written, carrying the fake door
 *
 * The module pages themselves are module-v1.css. Nothing here loads on one.
 */

.mod{position:relative;display:block;border:1px solid var(--line);border-radius:15px;
 background:#fff;padding:15px;text-decoration:none;color:var(--ink);margin:10px 0}
.mod .ico{position:absolute;top:50%;right:-10px;font-size:74px;line-height:1;z-index:0;
 transform:translateY(-50%) rotate(-8deg);opacity:.62}
.mod .scrim{position:absolute;inset:0;z-index:1;border-radius:15px;
 background:linear-gradient(100deg,#fff 58%,rgba(255,255,255,.82) 78%,rgba(255,255,255,0) 100%)}
.mod > .in{position:relative;z-index:2}
.mod .ttl{font-weight:800;font-size:17.5px;line-height:1.18;padding-right:30px}
.mod .dsc{font-size:12.5px;color:var(--muted);margin-top:5px;padding-right:30px;line-height:1.5}
.mod .tag{display:inline-block;margin-top:9px;font-size:10.5px;font-weight:800;
 letter-spacing:.05em;text-transform:uppercase;border-radius:20px;padding:4px 9px;
 background:#eef2ff;color:#22397a}
.mod .tag.soon{background:#f1f3f7;color:#5c6a86}
.mod .tag.price{background:#e7f6ee;color:#166b40}
.mod.soon{opacity:.82}
/* An open door makes the card tall, and the background glyph is centred on the
   card, so it drifts into the middle of the form. Both it and its scrim go when
   the card is open, and the card comes back to full strength while it is. */
.mod.open{opacity:1}
.mod.open .ico,.mod.open .scrim{display:none}

/* ---- a module on a series page -------------------------------------------
   These are numbered, because a series is taught in order and the number is the
   only thing on the card that says so. */
.mod .num{position:absolute;top:15px;left:15px;z-index:2;width:26px;height:26px;
 border-radius:50%;background:#eef2ff;color:#22397a;font-size:13px;font-weight:800;
 display:flex;align-items:center;justify-content:center}
/* display:block matters. .in is a span, and padding-left on an INLINE box does
   not move a block-level child, so the title sat underneath the number badge. */
.mod .num ~ .in{display:block;padding-left:36px}
/* .read is added by learn-v4.js when the reader has finished that module. */
.mod.read .num{background:var(--accent);color:#fff}
.mod .tick{display:inline-block;margin-top:9px;margin-left:6px;font-size:10.5px;
 font-weight:800;letter-spacing:.05em;text-transform:uppercase;border-radius:20px;
 padding:4px 9px;background:#e7f6ee;color:#166b40}
/* [hidden] is a UA rule and any author display rule beats it, so a tick set to
   hidden would stay on screen. Same trap as the door form below. */
.mod .tick[hidden]{display:none}

/* ---- per-module colour on a SERIES page ------------------------------------
   The tokens themselves are generated per page by tools/palette.py, because the
   hues depend on how many modules the series has. This is only what consumes
   them, and it mirrors the learn.html treatment exactly: a keyline above the
   title, coloured title, tag and border, and a tint felt rather than seen.

   Deliberately NOT a filled wash. The games menu gets one; this section is
   reference material a reader pays for, and Luke's instruction on the learn.html
   palette was "a more professional colour scheme though - likely more muted".
   Tint sits at 1.105:1 against white where the games menu sits at 1.32. */
.mod{--mbg:255,255,255;--mln:var(--line);--mac:var(--accent);--mtg:#eef2ff;--mds:var(--muted)}
.mod[data-mc]{background:rgb(var(--mbg));border-color:var(--mln)}
/* RGB triple, not a hex, so the scrim can reuse the tint at three alpha stops. */
.mod[data-mc] .scrim{background:linear-gradient(100deg,rgb(var(--mbg)) 58%,rgba(var(--mbg),.82) 78%,rgba(var(--mbg),0) 100%)}
.mod[data-mc] .ttl{color:var(--mac)}
.mod[data-mc] .dsc{color:var(--mds)}
.mod[data-mc] .tag{background:var(--mtg);color:var(--mac)}
/* THE ONE TOKEN THAT WAS COPIED RATHER THAN SOLVED, and it failed for exactly
   the reason every other one on this card is solved. The "Not written yet" pill
   stays deliberately NEUTRAL — a greyed module should not advertise itself in
   the series' own ink — but neutral still has to be legible, and #5c6a86 on
   #f1f3f7 measures 3.9:1 declared and 3.42:1 once the card's opacity .82 is
   applied to both. Caught by the composited assertion in test_atlas.js, which
   is the assertion that exists because this is the third time.
   #454f64 is the same hue walked down until it clears AA as SEEN: 4.71:1. */
.mod[data-mc] .tag.soon{background:#f1f3f7;color:#454f64}
.mod[data-mc] .num{background:var(--mac);color:#fff}
.mod[data-mc].read .num{background:var(--good)}
/* The editorial keyline. Marks the module without flooding the card, and it is
   drawn with ::before so no markup moves. */
.mod[data-mc] .ttl::before{content:"";display:block;width:38px;height:4px;
 background:var(--mac);border-radius:2px;margin:1px 0 9px}
.mod .ttl,.mod .dsc{display:block}
/* The glyph is 74px and bled off the right edge, so 30px of padding was not
   enough to keep a description clear of it — on the longest hooks the last line
   ran under the picture. The scrim keeps it legible; this keeps it tidy. */
.mod[data-mc] .ttl,.mod[data-mc] .dsc{padding-right:52px}
/* THE CLIP THAT MUST SHIP WITH THE GLYPH. `.ico` is deliberately oversized and
   bled off the right edge; without this it paints outside the card and sits on
   the page background. That shipped on learn.html and was reported by Luke, and
   it happened because the bleed was copied from the games menu and the clip was
   not. It lives here, on .mod, so a new card type cannot repeat it. */
.mod{overflow:hidden}

/* A SERIES NOBODY CAN READ YET, on /learn.html. It is greyed rather than
   coloured, because the colour on this page means "there is something behind
   this card". Tokens are neutral and solved the same way the module cards are:
   #454f64 title on the composited tint clears AA, and the tint itself sits at
   1.06:1 against white so the card reads as set back rather than as disabled.
   It carries no href, so it also cannot be tapped through to an empty page. */
.mod.ser.soon{--mbg:244,245,247;--mln:#d7dbe3;--mac:#454f64;--mtg:#e9ecf1;--mds:#5c6a86}
.mod.ser.soon{background:rgb(var(--mbg));border-color:var(--mln);opacity:1}
.mod.ser.soon .ico{filter:grayscale(1);opacity:.55}

/* THE PARTIAL FIGURE, on the row and never on the bar. A bar that advanced on a
   half-finished module would make "completed" mean two things at once. Quieter
   than the tick because it is a position rather than an achievement. */
.mod .part{display:inline-block;margin-top:9px;margin-left:6px;font-size:10.5px;
 font-weight:800;letter-spacing:.05em;text-transform:uppercase;border-radius:20px;
 padding:4px 9px;background:#fff4e5;color:#8a5300}
.mod .part[hidden]{display:none}
.mod.partly .num{background:#f0a202;color:#fff}

/* ---- D1. CONTINUE FIRST, THE GRID IMMEDIATELY BELOW ------------------------
   The largest thing on the page for a returning reader is one card naming the
   next unfinished module. The full list sits directly beneath it on the same
   screen: no tap, no accordion, no second page. B6's finding is about what a
   reader is asked to DECIDE, not about what they are allowed to REACH. */
.serstate{margin:0 0 18px}
.cont{border:1px solid var(--accent);border-radius:15px;background:#f7f9ff;padding:15px}
.cont[hidden],.startblk[hidden]{display:none}
.cont .conth{margin:0;font-size:10.5px;font-weight:800;letter-spacing:.06em;
 text-transform:uppercase;color:var(--accent)}
.cont .contt{margin:5px 0 0;font-weight:800;font-size:17.5px;line-height:1.18}
.cont .contt #scontn{color:var(--muted)}
.cont .small{margin:5px 0 0;color:var(--muted);font-size:12.5px}
.cont .btn{margin-top:12px}
.startblk .btn{width:100%;text-align:center}

/* The recommended-order line. Once, above the list, and it explains WHY the
   order is recommended rather than only asserting it. */
.order{margin:0 0 12px;color:var(--muted);line-height:1.55}

/* ---- the purchase, which the series page carries --------------------------
   One decision at one join. openHPI measured end-to-end completion falling from
   64% to 15% when a course was sold as separately-entered modules, and the loss
   sat entirely at the joins. */
.buy{position:relative;border:1px solid var(--accent);border-radius:15px;background:#f7f9ff;
 padding:15px;margin:14px 0 6px}
.buy .btitle{display:block;font-weight:800;font-size:16px;line-height:1.2}
.buy .bcopy{display:block;font-size:12.5px;color:var(--muted);margin-top:6px;line-height:1.55}
.buy .tellme{background:#fff}

/* One form per series page, so an unwritten module asks quietly and in words
   rather than with a seventh button competing with the purchase. */
.want{margin-top:10px;font:inherit;font-size:12.5px;font-weight:700;cursor:pointer;
 background:none;border:0;padding:0;color:var(--accent);text-decoration:underline;
 text-underline-offset:3px}
.want:hover{text-decoration-thickness:2px}

/* ---- the fake door -------------------------------------------------------
   It is deliberately quiet until it is opened: the point of the card is to say
   honestly that the module is not written, and the point of the button is to
   find out whether anyone minds. */
.tellme{margin-top:11px;font:inherit;font-size:12.5px;font-weight:800;cursor:pointer;
 background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px 12px;
 color:var(--accent)}
.tellme:hover{border-color:var(--accent)}
.door{margin-top:11px;border-top:1px solid var(--line);padding-top:11px}
.door .dcopy{font-size:12.5px;line-height:1.5;margin:0 0 9px}
.door form{display:flex;gap:6px;flex-wrap:wrap}
/* [hidden] is a UA rule and any author display rule beats it, so a form set
   to hidden would stay on screen. Caught by tools/test_learn.js. */
.door form[hidden]{display:none}
.door input{flex:1 1 190px;min-width:0;font:inherit;font-size:14px;padding:9px 11px;
 border:1px solid var(--line);border-radius:9px;background:#fff;color:var(--ink)}
.door button{font:inherit;font-size:13px;font-weight:800;cursor:pointer;padding:9px 13px;
 border:0;border-radius:9px;background:var(--accent);color:#fff}
.door button[disabled]{opacity:.6;cursor:default}
.door .saidit{font-size:12px;margin:8px 0 0;min-height:1em;color:var(--ink)}
.door .dsmall{font-size:11px;color:var(--muted);margin:6px 0 0;line-height:1.5}

.anat li{font-size:13.5px;line-height:1.55;margin:0 0 9px}
.anat li b{font-weight:800}

/* ---- the decisions page ---------------------------------------------------
 * One row per module in series order. A row a reader has not reached carries no
 * answer in the document at all, so there is nothing here to hide: the styling
 * only has to make a taken decision look different from one still ahead.
 */
.declist{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:10px}
.decrow{border:1px solid var(--line);border-radius:14px;padding:12px 14px;
  background:var(--card)}
.decrow .pin{display:block;font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);font-weight:800}
.decrow h3{margin:2px 0 0;font-size:16px;line-height:1.3}
.decrow h3 a{color:inherit;text-decoration:none}
.decrow h3 a:hover,.decrow h3 a:focus-visible{text-decoration:underline}
.decrow .decmine{margin:8px 0 0;font-weight:700;line-height:1.4}
.decrow .decreal{margin:3px 0 0;color:var(--muted);line-height:1.5}
.decrow .decnone{margin:8px 0 0;color:var(--muted);font-size:13px}
/* Matching the government is not a score and must not read as one. The left
 * edge marks which of the two happened and nothing carries a tick or a cross. */
.decrow.same{border-left:3px solid var(--ok,#1a7f4b)}
.decrow.differ{border-left:3px solid var(--accent,#2f5bd8)}
.decspine{margin-top:16px}
.spinel{margin:10px 0 0;padding-left:20px;display:grid;gap:6px;line-height:1.5}
.spinel li{padding-left:2px}


/* ---- DELIBERATE NAVIGATION -------------------------------------------------
   Luke, 18 August: "we need deliberate buttons for any navigation users might
   want (not the current tiny links users can use)".
 
   The breadcrumb stays, because it is the page's structured breadcrumb and it
   is what a search result renders. It is not navigation a thumb can use, and it
   was doing both jobs badly. A reader on a phone now gets a real target of at
   least 44px for every move they might reasonably want to make. */
.navrow{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 16px}
.navbtn{display:inline-flex;align-items:center;gap:7px;min-height:44px;
 padding:10px 14px;border:1px solid var(--line);border-radius:11px;
 background:var(--card);color:var(--ink);font-weight:700;font-size:13.5px;
 line-height:1.25;text-decoration:none}
.navbtn:hover{border-color:var(--accent);color:var(--accent)}
.navbtn .arw{font-weight:800;color:var(--muted)}
.navbtn:hover .arw{color:var(--accent)}
.navbtn.wide{flex:1 1 100%;justify-content:center}
.navrow.foot{margin:22px 0 0}

.navbtn .nb{display:flex;flex-direction:column;align-items:flex-start;gap:1px}
.navbtn .pos{font-size:11.5px;font-weight:600}
.navbtn.wide .nb{align-items:center}


/* The demand control on an unwritten module was an underlined link at 12.5px,
   which is the same "tiny link doing a button's job" Luke called out on the
   module pages. It is the only thing a reader can DO on an unwritten card, so
   it gets a real target and the module's own ink — the same treatment
   learn.html gives its `.tellme`. */
.mod[data-mc] .want{display:inline-flex;align-items:center;min-height:44px;
 margin-top:11px;padding:9px 14px;border:1px solid var(--mln);border-radius:11px;
 background:var(--card);color:var(--mac);text-decoration:none;font-size:13px}
.mod[data-mc] .want:hover{border-color:var(--mac)}

/* THE NOTICE BOX at the top of /learn.html. It is the .buy block with its
   panel already open and a feedback form under it, so the two things a reader
   can do here are both visible rather than behind a press. The inner widget
   draws its own card; on top of this one that reads as a box inside a box, so
   its border and padding come off and the two are separated by a rule. */
.buy.notice{margin:14px 0 18px}
.buy.notice .door{border-top:0;padding-top:9px;margin-top:9px}
.buy.notice #feedbackSlot{margin-top:14px;border-top:1px solid var(--line);padding-top:12px}
.buy.notice #feedbackSlot .fbsec,.buy.notice .fbsec{margin:0}
.buy.notice .fbbox{border:0;padding:0;background:transparent;border-radius:0}
.buy.notice .fbk{margin-bottom:7px}
.buy.notice .fbcap{font-size:12.5px;margin-bottom:9px}
