/* ============================================================
   JotTower — assets/css/style.css
   One stylesheet for the whole product.

   Palette (fixed by the design brief): paper, ink, muted, line,
   and one amber accent — "rise" — reserved for growth: the
   wordmark's second half, the tower on every shelf card, the
   primary button. Nothing else is amber.

   Type: one family, DM Sans, for everything. Headings and the
   wordmark are set heavier and larger, not in a second face.
   Falls back to the system stack if the font files can't load.

   The signature element is the shelf: cards stand on a plank,
   each carrying a tower whose height is its entry count.
   Everything else stays quiet.
   ============================================================ */

:root {
    --paper: #f7f9fa;
    --paper-2: #eef2f4;
    --card: #ffffff;
    --ink: #1c2b33;
    --ink-2: #33454f;
    --muted: #5c6e78;
    --line: #dde5e9;
    --line-2: #c9d3d9;
    /* The logo blue. The mark's T and the wordmark's "Topic" are the same
       colour by definition — change it here and both follow. */
    --mark: #2f6db0;
    --rise: #e8930c;
    --rise-deep: #c97a05;
    --rise-bg: #fdf3e3;
    --rise-line: #f0d5a6;
    --ok-bg: #e8f4ec;
    --ok: #2e7d4f;
    --ok-line: #bfdfcb;
    /* Uncovered checkpoints. Deliberately NOT a warning colour: a bar that is
       mostly uncovered is the normal state of an honest learning log, not a
       fault to be corrected. Red made a half-written tower look broken. */
    --todo: #6b8fb5;
    --todo-deep: #4f7499;
    --warn-bg: #fbeaea;
    --warn: #a33a3a;
    --warn-line: #ebc3c3;

    --sans: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        sans-serif;

    --col: 880px;
    --radius: 10px;
    --radius-sm: 7px;
    --shadow: 0 1px 2px rgba(28, 43, 51, 0.06),
        0 6px 18px -12px rgba(28, 43, 51, 0.18);
}

* {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font: 16px/1.6 var(--sans);
    font-feature-settings: "kern", "liga";
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--ink-2);
}

main {
    max-width: var(--col);
    margin: 0 auto;
    padding: 0 24px 96px;
}

/* ============================================================
   Masthead
   ============================================================ */

header.mast {
    max-width: var(--col);
    margin: 0 auto;
    padding: 30px 24px 18px;
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
}

.wordmark {
    font-family: var(--sans);
    font-weight: 700;
    font-size: 24px;
    letter-spacing: -0.02em;
    text-decoration: none;
    color: var(--mark);
    line-height: 1;
}

.wordmark .rise {
    color: var(--rise);
    position: relative;
    top: -3px;
}

.mast nav {
    display: flex;
    margin-left: 28px;
}

.mast nav a + a {
    margin-left: 20px;
}

.mast nav a {
    color: var(--muted);
    text-decoration: none;
    font-size: 15px;
    padding-bottom: 2px;
    border-bottom: 1.5px solid transparent;
}

.mast nav a:hover {
    color: var(--ink);
    border-bottom-color: var(--line-2);
}

.mast .who {
    margin-left: auto;
    display: flex;
    align-items: baseline;
    font-size: 15px;
    color: var(--muted);
}

.mast .who > * + * {
    margin-left: 14px;
}

.mast .who span {
    color: var(--ink-2);
}

.mast .who a {
    color: var(--muted);
    text-decoration: none;
}

.mast .who a:hover {
    color: var(--ink);
}

.mast .who form {
    display: inline;
}

.mast .who button.link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-size: 15px;
    color: var(--muted);
    cursor: pointer;
}

.mast .who button.link:hover {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ============================================================
   Type scale
   ============================================================ */

h1 {
    font-family: var(--sans);
    font-weight: 700;
    font-size: 30px;
    line-height: 1.15;
    letter-spacing: -0.02em;
    margin: 28px 0 8px;
}

h2 {
    font-family: var(--sans);
    font-weight: 600;
    font-size: 20px;
    line-height: 1.25;
    margin: 40px 0 14px;
}

h3 {
    font-family: var(--sans);
    font-weight: 600;
    font-size: 19px;
    margin: 0 0 6px;
}

.sub {
    color: var(--muted);
    font-size: 15px;
    margin: 0 0 22px;
}

.small {
    font-size: 13.5px;
    color: var(--muted);
}

.empty {
    color: var(--muted);
    margin: 0;
    padding: 28px 22px;
    border: 1.5px dashed var(--line-2);
    border-radius: var(--radius);
    background: transparent;
}

/* Page header row: title on the left, figures on the right */
.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    margin-bottom: 26px;
}

.page-head h1 {
    margin-bottom: 0;
}

.figures {
    display: flex;
    padding-bottom: 6px;
}

.figures .stat + .stat {
    margin-left: 26px;
}

.figures .stat {
    font-size: 15px;
    color: var(--muted);
    white-space: nowrap;
}

.figures .stat b {
    font-family: var(--sans);
    font-weight: 600;
    font-size: 21px;
    color: var(--ink);
    margin-right: 5px;
}

/* A heading with a small control on its right (the search) */
.h-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    margin-top: 40px;
    margin-bottom: 14px;
}

.h-row h2 {
    margin: 0;
}

/* ============================================================
   Cards, forms, buttons
   ============================================================ */

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 22px;
    margin-bottom: 16px;
    box-shadow: var(--shadow);
}

/* The capture card is the product's front door: bigger, warmer edge */
.card.capture {
    padding: 22px 22px 18px;
    border-color: var(--rise-line);
}

textarea {
    display: block;
    width: 100%;
    min-height: 130px;
    resize: vertical;
    font: inherit;
    font-size: 17px;
    line-height: 1.6;
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    background: #fff;
}

textarea::placeholder,
input::placeholder {
    color: #8a9aa3;
}

textarea:focus,
input:focus,
select:focus {
    outline: none;
    border-color: var(--rise);
    box-shadow: 0 0 0 3px rgba(232, 147, 12, 0.18);
}

button:focus-visible,
a:focus-visible {
    outline: 2px solid var(--rise);
    outline-offset: 2px;
}

input[type="date"],
input[type="search"],
input[type="text"],
input[type="email"],
input[type="password"],
select {
    font: inherit;
    font-size: 15px;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--ink);
}

input[type="search"] {
    -webkit-appearance: none;
    appearance: none;
}

.row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 12px;
}

.row > * + * {
    margin-left: 10px;
}

.row.end {
    justify-content: flex-end;
}

button,
.btn {
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid var(--rise);
    border-radius: var(--radius-sm);
    background: var(--rise);
    color: #fff;
    padding: 10px 18px;
    text-decoration: none;
    display: inline-block;
    line-height: 1.3;
}

button:hover,
.btn:hover {
    background: var(--rise-deep);
    border-color: var(--rise-deep);
}

button.quiet,
.btn.quiet {
    background: #fff;
    color: var(--ink-2);
    border-color: var(--line-2);
    font-weight: 500;
}

button.quiet:hover,
.btn.quiet:hover {
    background: var(--paper-2);
    color: var(--ink);
    border-color: var(--line-2);
}

/* Delete: a quiet link on the same line as the "no need to retype it" note,
   not a button. Removing a jotting should never be the easiest thing on the
   card. A form is still used, so it stays a POST with a CSRF token. */
.inline-delete {
    display: inline;
}

button.linkish {
    background: none;
    border: 0;
    padding: 0;
    margin: 0 0 0 10px;
    font: inherit;
    color: #8a8e97;
    text-decoration: underline;
    cursor: pointer;
}

button.linkish:hover {
    color: #b0413e;
    background: none;
}

/* Search: one compact control */
.search {
    display: flex;
    align-items: center;
}

.search button {
    margin-left: 8px;
}

.search input[type="search"] {
    width: 260px;
    max-width: 100%;
}

/* ============================================================
   Banners — one message, one left edge of colour
   ============================================================ */

.banner {
    border-radius: var(--radius-sm);
    padding: 13px 16px 13px 18px;
    margin: 14px 0;
    font-size: 15px;
    border: 1px solid var(--line);
    border-left-width: 4px;
    background: var(--card);
}

.banner.new-shelf {
    background: var(--rise-bg);
    border-color: var(--rise-line);
    border-left-color: var(--rise);
}

.banner.saved {
    background: var(--ok-bg);
    border-color: var(--ok-line);
    border-left-color: var(--ok);
    color: var(--ok);
}

.banner.saved a {
    color: inherit;
}

.banner.unfiled {
    background: var(--warn-bg);
    border-color: var(--warn-line);
    border-left-color: var(--warn);
    color: var(--warn);
}

.banner form {
    display: inline;
}

.banner .row {
    margin-top: 10px;
}

/* ============================================================
   The shelf — cards stand on a plank; each carries its tower
   ============================================================ */

.shelves {
    display: flex;
    flex-wrap: wrap;
    margin-right: -14px;
}

.shelf-card {
    position: relative;
    flex: 1 1 200px;
    max-width: calc(33.333% - 14px);
    margin: 0 14px 14px 0;
    min-height: 112px;
    background: var(--card);
    border: 1px solid var(--line);
    border-bottom: 3px solid var(--line-2); /* the plank */
    border-radius: var(--radius) var(--radius) 4px 4px;
    padding: 16px 16px 14px 26px;
    text-decoration: none;
    color: var(--ink);
    overflow: hidden;
    box-shadow: var(--shadow);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}

.shelf-card:hover {
    border-color: var(--rise-line);
    border-bottom-color: var(--rise);
}

/* The tower: width fixed, height = entry_count / max × 48px (set inline) */
.shelf-card .bar {
    position: absolute;
    left: 10px;
    bottom: 0;
    width: 8px;
    background: var(--rise);
    border-radius: 3px 3px 0 0;
}

/* Per-entry move control: collapsed by default so the log reads as a log. */
.entry-body details.move {
    margin-top: 10px;
}

.entry-body details.move > summary {
    cursor: pointer;
    color: var(--muted);
    list-style: none;
    display: inline-block;
}

.entry-body details.move > summary::-webkit-details-marker {
    display: none;
}

.entry-body details.move > summary::before {
    content: "↪ ";
}

.entry-body details.move[open] > summary {
    color: var(--ink);
}

.move-form {
    margin-top: 8px;
    flex-wrap: wrap;
}

.move-form select {
    max-width: 300px;
}

.move-form input[type="text"] {
    flex: 1;
    min-width: 200px;
}

/* A covered checkpoint is a link to its receipt. */
.cp-list li.jump {
    cursor: pointer;
    border-radius: var(--radius-sm);
    padding: 4px 6px;
    margin-left: -6px;
}

.cp-list li.jump:hover,
.cp-list li.jump:focus-visible {
    background: var(--paper-2);
    outline: none;
}

/* Brief highlight on the entry that was jumped to, so the scroll lands
   somewhere obvious rather than leaving the reader hunting. */
.entry.flash {
    animation: entry-flash 1.6s ease-out;
}

@keyframes entry-flash {
    0% {
        background: var(--rise-bg);
    }
    100% {
        background: transparent;
    }
}

/* Reading ahead: the topic's checklist starts above this learner's class, so
   there is no bar to draw. One quiet line, not a card — it replaces a thin
   strip and should not weigh more than the thing it stands in for. */
.ahead-note {
    margin: 0 0 22px;
    padding: 0 0 0 14px;
    border-left: 2px solid var(--line);
    font-family: var(--sans);
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--muted);
}

/* Shown when the remaining list is open only because the build-time reveal
   override is on. Deliberately conspicuous. */
.override-note {
    padding: 7px 10px;
    border: 1px solid var(--rise-line);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--ink);
}

/* Closed, the capture card is nothing but the subject dropdown — no panel, no
   border, no shadow. The page below is the point once a learner has shelves,
   and a permanently open box pushes all of it past the fold. Opening restores
   the card so the writing surface reads as a surface. */
.card.capture {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    padding: 0;
    margin-bottom: 8px;
    transition: background 220ms ease, border-color 220ms ease,
        box-shadow 220ms ease, padding 220ms ease;
}

.card.capture.open {
    background: var(--card);
    border-color: var(--rise-line);
    box-shadow: var(--shadow);
    padding: 18px 20px 20px;
    margin-bottom: 26px;
}

.card.capture.instant {
    transition: none;
}

/* The capture box stays shut until a subject is chosen. grid-template-rows
   0fr -> 1fr animates a height the content decides for itself, so the box does
   not need a hardcoded max-height that clips a long symbol pad. */
.capture-rest {
    /* ONE grid child, deliberately. 0fr -> 1fr animates a height the content
       decides for itself, but only for rows the template defines — several
       children would land in implicit rows, which collapse wrongly when shut
       and divide the space equally when open, giving the date row the same
       height as the textarea. The inner wrapper keeps it to a single row. */
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 240ms ease, opacity 200ms ease;
}

.capture-rest > .capture-rest-inner {
    overflow: hidden;
    min-height: 0;
}

.capture-rest.open {
    grid-template-rows: 1fr;
    opacity: 1;
}

.capture-rest.open > .capture-rest-inner {
    overflow: visible;
}

/* Restored form state on a back-navigation: open, but do not replay the
   animation for something the learner did not just do. */
.capture-rest.instant {
    transition: none;
}

@media (prefers-reduced-motion: reduce) {
    .capture-rest {
        transition: opacity 120ms ease;
    }
}

/* Search sits in the page head now that the page title is gone. It takes the
   space the h1 held, so the head row keeps its shape and the figures stay
   right-aligned. */
.head-search {
    flex: 1;
    max-width: none;
}

.head-search input[type="search"] {
    width: 100%;
}

@media (max-width: 700px) {
    .head-search {
        max-width: none;
    }
}

/* Short note under a sidebar block title. */
.side-note {
    font-family: var(--sans);
    font-size: 12px;
    line-height: 1.55;
    color: var(--muted);
    margin: -2px 0 10px;
}

/* ---- Subject filter tabs above the shelf grid ---- */
.subject-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 18px;
}

.subject-tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    font-family: var(--sans);
    font-size: 13px;
    color: var(--muted);
    text-decoration: none;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 999px;
}

.subject-tab:hover {
    color: var(--ink);
    border-color: var(--rise-line);
}

.subject-tab.on {
    color: var(--ink);
    font-weight: 600;
    border-color: var(--rise);
}

.subject-tab .n {
    font-size: 11.5px;
    color: var(--muted);
}

.subject-tab.on .n {
    color: var(--rise);
}

/* Section heading when the grid is showing every subject at once. */
.subject-heading {
    font-family: var(--sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 26px 0 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--line);
}

.subject-heading:first-of-type {
    margin-top: 4px;
}

/* Subject under a tower name in the sidebar. */
.side-subject {
    display: block;
    font-style: normal;
    font-size: 10.5px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    margin-top: 1px;
}

/* Subject, top-left on every card. Not decoration: two subjects can each own
   a shelf called "Functions" or "Character", so the card is ambiguous without
   it. margin-bottom:auto pins it to the top of a card whose other content is
   bottom-aligned. */
/* Capture symbol pad — only rendered for subjects that define one. */
.symbol-pad {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 16px;
    margin: 0 0 10px;
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

/* The hidden attribute sets display:none at low specificity, so the
   display:flex above beats it and an empty pad still occupies a row.
   This puts it back. */
.symbol-pad[hidden] {
    display: none;
}

.symbol-group {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
}

.symbol-group-label {
    font-family: var(--sans);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-right: 3px;
}

.symbol-key {
    min-width: 34px;
    padding: 4px 8px;
    font-size: 15px;
    line-height: 1.2;
    background: var(--card);
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 6px;
    cursor: pointer;
}

.symbol-key:hover {
    border-color: var(--rise-line);
    background: var(--card);
}

@media (max-width: 860px) {
    .symbol-pad {
        gap: 8px 10px;
    }
    .symbol-key {
        min-width: 40px;
        padding: 7px 9px;
        font-size: 16px;
    }
}

.shelf-card .subject {
    margin-bottom: auto;
    font-family: var(--sans);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}

.subject-eyebrow {
    font-family: var(--sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 2px;
}

.shelf-card .name {
    font-family: var(--sans);
    font-weight: 600;
    font-size: 17px;
    line-height: 1.25;
}

.shelf-card .count {
    color: var(--muted);
    font-size: 13.5px;
    margin-top: 3px;
}

@media (max-width: 700px) {
    .shelf-card {
        max-width: calc(50% - 14px);
    }
}

@media (max-width: 460px) {
    .shelf-card {
        max-width: calc(100% - 14px);
    }
}

/* ============================================================
   Entries
   ============================================================ */

/* Plain entry: used by the unfiled tray, search results, the calendar day list
   and the map's written index. Deliberately unstyled beyond spacing — those
   surfaces stack entries with their own controls beside them. */
.entry {
    border-bottom: 1px solid var(--line);
    padding: 14px 2px;
    font-size: 16px;
}

.entry:first-child {
    padding-top: 4px;
}

.entry:last-child {
    border-bottom: none;
    padding-bottom: 4px;
}

.entry .meta {
    color: var(--muted);
    font-size: 13.5px;
    margin-top: 5px;
}

/* The shelf page only. A shelf is a column of things this learner wrote, in
   order: the date runs down a gutter so the page reads as a log with a spine,
   and the words sit in a measure short enough to actually read. */
.entry-log {
    display: grid;
    grid-template-columns: 62px minmax(0, 1fr);
    gap: 0 22px;
    padding: 22px 0;
    font-size: 16.5px;
    border-bottom: none;
}

.entry-log + .entry-log {
    border-top: 1px solid var(--line);
}

.entry-log:first-child {
    padding-top: 6px;
}

.entry-log:last-child {
    padding-bottom: 6px;
}

.entry-when {
    padding-top: 3px;
    text-align: right;
}

.entry-when a {
    text-decoration: none;
    color: var(--muted);
    display: block;
    line-height: 1.1;
}

.entry-when .d {
    display: block;
    font-family: var(--sans);
    font-size: 19px;
    font-weight: 500;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}

.entry-when .m {
    display: block;
    font-family: var(--sans);
    font-size: 12px;
    margin-top: 1px;
}

.entry-when a:hover .d {
    color: var(--rise);
}

.entry-body {
    max-width: 64ch;
    line-height: 1.68;
}

.entry-body p {
    margin: 0 0 0.85em;
}

.entry-body p:last-child {
    margin-bottom: 0;
}

@media (max-width: 700px) {
    .entry-log {
        grid-template-columns: 1fr;
        gap: 6px;
    }

    .entry-when {
        text-align: left;
    }

    .entry-when a {
        display: flex;
        gap: 5px;
        align-items: baseline;
    }

    .entry-when .d {
        font-size: 14px;
    }
}

.entry .meta a {
    color: var(--muted);
}

.entry .meta.row {
    margin-top: 8px;
}

/* ============================================================
   Ambiguity modal
   ============================================================ */

dialog {
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 26px;
    max-width: 500px;
    width: calc(100% - 40px);
    background: var(--card);
    color: var(--ink);
    box-shadow: 0 24px 60px -20px rgba(28, 43, 51, 0.35);
}

dialog::backdrop {
    background: rgba(28, 43, 51, 0.45);
}

dialog .why {
    color: var(--muted);
    font-size: 15px;
    margin: 0 0 16px;
}

.candidate {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    width: 100%;
    text-align: left;
    margin: 8px 0;
    padding: 12px 16px;
    background: #fff;
    color: var(--ink);
    border: 1px solid var(--line-2);
    font-weight: 500;
}

.candidate:hover {
    border-color: var(--rise);
    background: var(--rise-bg);
    color: var(--ink);
}

.candidate .cnt {
    color: var(--muted);
    font-weight: 400;
    font-size: 13.5px;
}

/* ============================================================
   Auth pages: a narrow sheet under a large wordmark
   ============================================================ */

/* Sign in and sign up. The card is wide enough for two fields side by side,
   because a student's form is long and a single column of ten boxes reads as
   a chore. A short form (sign in) simply has one column and stays narrow. */
.auth {
    max-width: 680px;
    margin: 30px auto 0;
}

.auth.auth-narrow {
    max-width: 440px;
}

.auth h1 {
    margin-top: 0;
    font-size: 1.7rem;
    letter-spacing: -0.01em;
}

.auth > p.small {
    color: var(--muted);
    margin-top: 4px;
}

.auth .card {
    padding: 28px 30px;
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(16, 20, 28, 0.04), 0 8px 24px rgba(16, 20, 28, 0.06);
}

/* Two columns once there is room; the pairs that belong together sit on one
   row, and anything marked .field-wide keeps the full width. */
.auth .fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0 18px;
}

.auth .field-wide {
    grid-column: 1 / -1;
}

/* A pair that must stay a pair. The auto-fit grid above drops to one column
   whenever the card is under about 500px, which split the two password boxes
   onto separate rows; these two are asked for together and are shown together
   until the screen is genuinely narrow. */
.auth .fields-pair {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* The row of choices on the sign-up page: the two role pills on the left, and
   the owner's own link pushed to the right edge of the card. */
.auth .role-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
}

.auth .role-row .tab-right {
    margin-left: auto;
}

@media (max-width: 460px) {
    .auth .role-row { flex-wrap: wrap; }
    .auth .role-row .tab-right { margin-left: 0; }
}

@media (max-width: 480px) {
    .auth .fields-pair { grid-template-columns: 1fr; }
}

.auth .field {
    display: block;
    margin-bottom: 15px;
}

.auth .field span {
    display: block;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--muted);
    margin-bottom: 6px;
}

.auth .field input,
.auth .field select,
.auth .field textarea {
    width: 100%;
    font-size: 16px;
    padding: 11px 13px;
    border-radius: 9px;
    border: 1px solid var(--line);
    background: #fff;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.auth .field input:focus,
.auth .field select:focus,
.auth .field textarea:focus {
    outline: none;
    border-color: var(--accent, #c8892f);
    box-shadow: 0 0 0 3px rgba(200, 137, 47, 0.15);
}

.auth .field input::placeholder {
    color: #b3b6bd;
}

/* A field and its note are ONE cell of the grid. Left as separate children
   the note became a cell of its own and sat beside the box it belongs to. */
.auth .field-group {
    display: block;
}

.auth .field-group .field {
    margin-bottom: 4px;
}

.auth .hint {
    margin: 0 0 15px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--muted);
}

.auth button[type="submit"] {
    width: 100%;
    padding: 13px 18px;
    font-size: 16px;
    border-radius: 10px;
    margin-top: 8px;
}

.auth .alt {
    margin: 18px 0 0;
    font-size: 14.5px;
    color: var(--muted);
    text-align: center;
}

@media (max-width: 560px) {
    .auth .card { padding: 22px 20px; }
}

.auth .banner {
    margin-top: 0;
}

/* ============================================================
   Motion — only in answer to an action
   ============================================================ */

@media (prefers-reduced-motion: no-preference) {
    .shelf-card .bar {
        transition: height 0.4s ease;
    }

    button,
    .btn,
    .shelf-card {
        transition: background-color 0.15s ease, border-color 0.15s ease;
    }
}

/* ============================================================
   Calendar — one month, Monday first; days with jottings link
   ============================================================ */

.cal {
    padding: 18px 18px 14px;
}

.cal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}

.cal-head h2 {
    margin: 0;
    font-size: 19px;
}

.cal-head .btn {
    padding: 7px 12px;
    font-size: 14px;
}

.cal-grid {
    display: flex;
    flex-wrap: wrap;
}

.cal-wd {
    width: 14.2857%;
    font-size: 12.5px;
    color: var(--muted);
    padding: 4px 8px 8px;
}

.cal-day {
    width: 14.2857%;
    min-height: 66px;
    padding: 8px;
    border-top: 1px solid var(--line);
    color: var(--ink);
    text-decoration: none;
    display: block;
    position: relative;
}

.cal-day.blank {
    border-top-color: transparent;
}

.cal-day .n {
    display: block;
    font-size: 14px;
    color: var(--ink-2);
    width: 26px;
    height: 26px;
    line-height: 26px;
    text-align: center;
    border-radius: 13px;
}

.cal-day.future .n {
    color: var(--line-2);
}

.cal-day.today .n {
    box-shadow: inset 0 0 0 1.5px var(--line-2);
}

.cal-day .c {
    display: block;
    margin-top: 6px;
    font-size: 12.5px;
    color: var(--muted);
    padding-left: 10px;
    position: relative;
}

.cal-day .c::before {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    width: 6px;
    height: 6px;
    border-radius: 3px;
    background: var(--rise);
}

a.cal-day.has:hover {
    background: var(--paper-2);
    border-radius: var(--radius-sm);
}

a.cal-day.has .n {
    font-weight: 600;
}

.cal-day.picked {
    background: var(--rise-bg);
    border-radius: var(--radius-sm);
}

.cal-day.picked .n {
    background: var(--rise);
    color: #fff;
    font-weight: 600;
}

@media (max-width: 560px) {
    .cal-day {
        min-height: 54px;
        padding: 6px 4px;
    }

    .cal-day .c {
        font-size: 11px;
        padding-left: 8px;
    }

    .cal-day .c::before {
        top: 5px;
        width: 5px;
        height: 5px;
    }
}

/* ============================================================
   Map — the whole shelf as a graph plus an outline
   ============================================================ */

.map-card {
    padding: 10px;
}

.shelf-map {
    display: block;
    width: 100%;
    height: auto;
}

.shelf-map a circle:hover {
    fill: var(--rise-deep);
}

.map-shelf-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    border-bottom: 1px solid var(--line);
    padding-bottom: 10px;
    margin-bottom: 4px;
}

.map-shelf-head a,
.map-shelf-head > span:first-child {
    font-size: 18px;
    font-weight: 600;
    color: var(--ink);
    text-decoration: none;
}

.map-shelf-head a:hover {
    color: var(--rise-deep);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ============================================================
   Substance gate: the "needs one more sentence" tray state
   ============================================================ */

.needs-detail {
    margin-top: 10px;
    padding: 10px 12px;
    background: var(--rise-bg);
    border: 1px solid var(--rise-line);
    border-radius: var(--radius-sm);
}

.needs-detail .hint {
    color: var(--ink-2);
    margin-bottom: 4px;
}

.needs-detail form.row {
    margin-top: 6px;
}

.auth .field select {
    width: 100%;
    font: inherit;
    font-size: 16px;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--ink);
}

/* ============================================================
   Coverage — the green/red bar toward the learner's level
   ============================================================ */

.coverage-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 10px;
    font-size: 15px;
}

.progress {
    display: flex;
    width: 100%;
    height: 18px;
    border-radius: 9px;
    overflow: hidden;
    border: 1px solid var(--line-2);
    background: var(--paper-2);
}

.progress .seg {
    display: block;
    height: 100%;
    border: none;
    border-radius: 0;
    padding: 0;
    cursor: pointer;
}

.progress .seg.green {
    background: var(--ok);
}

.progress .seg.green:hover {
    background: #256b43;
}

.progress .seg.todo {
    background: var(--todo);
}

.progress .seg.todo:hover {
    background: var(--todo-deep);
}

.coverage-actions {
    justify-content: space-between;
    margin-top: 10px;
}

.cp-list {
    margin: 0 0 6px;
    padding-left: 22px;
    max-height: 340px;
    overflow-y: auto;
}

.cp-list li {
    margin-bottom: 8px;
}

.cp-list .receipt {
    color: var(--ok);
    margin-top: 2px;
}

/* Mini bar on the shelf cards */
.mini-progress {
    display: flex;
    height: 6px;
    border-radius: 3px;
    overflow: hidden;
    margin-top: 8px;
    background: var(--paper-2);
}

.mini-progress .green {
    background: var(--ok);
    height: 100%;
}

.mini-progress .todo {
    background: var(--todo);
    height: 100%;
}

.shelf-card .count.cov {
    margin-top: 3px;
}

/* Strength: solid green = demonstrated (counted); touched = pale green
   stripes over the to-cover colour, so it reads as started but not done
   and never as a second shade of progress. */
.progress .seg.touched,
.mini-progress .touched {
    background: repeating-linear-gradient(
        135deg,
        #8cc5a4 0,
        #8cc5a4 4px,
        var(--todo) 4px,
        var(--todo) 8px
    );
    height: 100%;
}

.progress .seg.touched:hover {
    background: repeating-linear-gradient(
        135deg,
        #79b794 0,
        #79b794 4px,
        var(--todo-deep) 4px,
        var(--todo-deep) 8px
    );
}

.badge {
    display: inline-block;
    font-size: 11.5px;
    font-weight: 600;
    padding: 1px 8px;
    border-radius: 9px;
    margin-left: 6px;
    vertical-align: 1px;
}

.badge.demo {
    background: var(--ok-bg);
    color: var(--ok);
    border: 1px solid var(--ok-line);
}

.badge.touch {
    background: #eff7f2;
    color: #4e8a68;
    border: 1px solid #cbe3d5;
}

/* Locked remaining-list: the shape without the names */
.lock-shape {
    font-size: 17px;
    font-weight: 600;
    margin: 0 0 10px;
}

/* ============================================================
   Sidebar layout — full width, nav on the left (2 Oct 2026)
   Modelled on the ElevenLabs app: the sidebar is pinned to the
   window's left edge at full height, white against the paper of
   the main column, and the main column takes all the remaining
   width. Until this date the whole layout sat in a 1160px box
   centred on the page, which left empty margins on wide screens.

   The sidebar is three stacked parts in a full-height column:
   .side-head (wordmark) and .side-foot (the learner) stay put,
   .side-scroll between them scrolls on its own when the lists are
   long. The main column keeps the window's own scrollbar, so the
   mobile URL bar and the browser's scroll restoration still work.
   ============================================================ */

.layout {
    display: flex;
    align-items: flex-start;
    min-height: 100vh;
}

.side {
    width: 256px;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--card);
    border-right: 1px solid var(--line);
}

.side-head {
    padding: 22px 20px 14px;
}

.side .wordmark {
    font-size: 22px;
}

.side .brand-mark {
    width: 28px;
    height: 28px;
}

.side-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 4px 12px 20px;
    scrollbar-width: thin;
    scrollbar-color: var(--line-2) transparent;
}

.side-scroll::-webkit-scrollbar {
    width: 8px;
}

.side-scroll::-webkit-scrollbar-thumb {
    background: var(--line-2);
    border-radius: 4px;
}

.side-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.layout main {
    flex: 1;
    min-width: 0;
    max-width: none;
    margin: 0;
    padding: 20px 40px 96px;
}

/* Nav rows: icon + label, a soft pill on hover, a filled pill for
   the page that is open. */
.side-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.side-nav a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--ink-2);
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.3;
}

.side-nav a .nav-ico {
    flex-shrink: 0;
    color: var(--muted);
}

.side-nav a:hover {
    background: var(--paper);
    color: var(--ink);
}

.side-nav a.on {
    background: var(--paper-2);
    color: var(--ink);
    font-weight: 600;
}

.side-nav a.on .nav-ico,
.side-nav a:hover .nav-ico {
    color: var(--ink);
}

.side-nav a:focus-visible,
.side-shelf:focus-visible,
.side-foot a:focus-visible,
.side-foot button:focus-visible {
    outline: 2px solid var(--mark);
    outline-offset: 1px;
}

/* The blocks under the nav: figures and shelf lists. */
.side-block {
    margin: 18px 0 0;
    padding: 16px 10px 0;
    border-top: 1px solid var(--line);
}

.side-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--muted);
    margin-bottom: 8px;
}

.side-stat {
    font-size: 14px;
    color: var(--muted);
    padding: 2px 0;
}

.side-stat b {
    color: var(--ink);
    font-size: 15px;
    margin-right: 4px;
}

.side-shelf {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    text-decoration: none;
    color: var(--ink-2);
    font-size: 14px;
    padding: 5px 8px;
    margin: 0 -8px;
    border-radius: 7px;
}

.side-shelf:hover {
    background: var(--paper);
    color: var(--ink);
}

.side-shelf.on {
    background: var(--paper-2);
    color: var(--ink);
    font-weight: 600;
}

.side-shelf .n {
    color: var(--muted);
    font-size: 13px;
    font-weight: 400;
}

/* The learner, pinned to the bottom of the sidebar. */
.side-foot {
    border-top: 1px solid var(--line);
    padding: 12px 12px 14px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.side-foot .who-link {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 6px 8px;
    border-radius: 8px;
    color: var(--ink);
    text-decoration: none;
    font-weight: 600;
    font-size: 14px;
}

.side-foot .who-link:hover {
    background: var(--paper);
}

.who-initial {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--mark);
    color: #fff;
    font-size: 14px;
    font-weight: 700;
}

.who-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.side-foot form {
    display: inline;
    flex-shrink: 0;
}

.side-signout {
    display: inline-flex;
    align-items: center;
    padding: 7px;
    border: none;
    border-radius: 8px;
    background: none;
    color: var(--muted);
    cursor: pointer;
}

.side-signout span {
    /* The label is for screen readers; the icon carries it on screen,
       and the button's title shows it on hover. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.side-signout:hover {
    background: var(--paper);
    color: var(--ink);
}

/* Small screens: the sidebar becomes a bar across the top, the nav
   rows sit side by side and scroll sideways if they don't fit. */
@media (max-width: 860px) {
    .layout {
        display: block;
    }

    /* Wordmark and account share the top line; the nav runs under them. */
    .side {
        width: 100%;
        height: auto;
        position: static;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        border-right: none;
        border-bottom: 1px solid var(--line);
    }

    .side-head {
        flex: 1;
        order: 1;
        padding: 14px 16px 8px;
    }

    .side-scroll {
        order: 3;
        width: 100%;
        flex: none;
        overflow: visible;
        padding: 0 10px 8px;
    }

    .side-block {
        display: none; /* figures live in the pages on small screens */
    }

    .side-nav {
        flex-direction: row;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .side-nav a {
        flex-shrink: 0;
        gap: 8px;
        padding: 7px 10px;
        font-size: 14px;
    }

    .side-foot {
        order: 2;
        border-top: none;
        padding: 10px 10px 4px 0;
        gap: 2px;
    }

    .side-foot .who-link {
        padding: 4px;
    }

    .who-name {
        display: none; /* the initial stands for the learner on a phone */
    }

    .layout main {
        padding: 16px 18px 96px;
    }
}

.needs-detail.check {
    background: var(--warn-bg);
    border-color: var(--warn-line);
}

.needs-detail .tiny {
    font-size: 12px;
    color: var(--muted);
}

/* An overridden soundness doubt stays visible on the entry */
.entry .doubt {
    color: var(--warn);
    margin-top: 4px;
}

/* A corrected line: kept, but never presented as knowledge */
s.was-wrong {
    color: #9aa9b1;
    text-decoration-color: #c4837c;
    font-size: 0.94em;
}

.paste-note {
    margin-top: 6px;
}

.paste-note.blocked {
    color: var(--warn);
}

/* ============================================================
   Subject colours — one very light tint per subject (18 Sept 2026)
   --s-bg   card and pill background
   --s-line border
   --s-ink  subject label, count, active pill
   The class comes from subject_css_class() in includes/subjects.php.
   ============================================================ */

.subj-maths     { --s-bg: #f2f4fc; --s-line: #d6dcf3; --s-ink: #3b4b9e; }
.subj-physics   { --s-bg: #fdf3ec; --s-line: #f3d5c1; --s-ink: #a34e22; }
.subj-chemistry { --s-bg: #f6f1fb; --s-line: #e0d3f0; --s-ink: #6e45a3; }
.subj-biology   { --s-bg: #eef7f1; --s-line: #cbe6d4; --s-ink: #2f7a49; }
.subj-history   { --s-bg: #fbf6ea; --s-line: #ecddb6; --s-ink: #86601a; }
.subj-geography { --s-bg: #edf6f6; --s-line: #c7e2e0; --s-ink: #23706b; }
.subj-civics    { --s-bg: #fcf1f4; --s-line: #f0d2da; --s-ink: #9a3552; }
.subj-economics { --s-bg: #eef5fc; --s-line: #cfe1f2; --s-ink: #2e6194; }

/* Shelf cards */
.shelf-card.subj {
    background: var(--s-bg);
    border-color: var(--s-line);
    border-bottom-color: var(--s-line);
}
.shelf-card.subj:hover {
    border-color: var(--s-ink);
    border-bottom-color: var(--s-ink);
}
.shelf-card.subj .subject {
    color: var(--s-ink);
}

/* Subject filter pills */
.subject-tab.subj {
    background: var(--s-bg);
    border-color: var(--s-line);
    color: var(--s-ink);
}
.subject-tab.subj:hover {
    border-color: var(--s-ink);
    color: var(--s-ink);
}
.subject-tab.subj .n {
    color: var(--s-ink);
    opacity: 0.8;
}
.subject-tab.subj.on {
    border-color: var(--s-ink);
    box-shadow: inset 0 0 0 1px var(--s-ink);
    color: var(--s-ink);
    font-weight: 600;
}
.subject-tab.subj.on .n {
    color: var(--s-ink);
    opacity: 1;
}

/* Subject headings in the grid, the eyebrow on a shelf page, the sidebar label */
.subject-heading.subj {
    color: var(--s-ink);
    border-bottom-color: var(--s-line);
}
.subject-eyebrow.subj,
.side-subject.subj {
    color: var(--s-ink);
}

/* ============================================================
   Entry form: subject and date pickers (18 Sept 2026)
   Larger, rounded controls with their own arrow. Once a subject is
   chosen, the pickers take that subject's light tint.
   ============================================================ */

.row.capture-head {
    gap: 12px;
    margin-top: 0;
}
.row.capture-head > * + * {
    margin-left: 0;
}
.capture-head label.small {
    font-weight: 600;
    color: var(--ink-2);
    letter-spacing: 0.01em;
}
.capture-head .capture-date {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    white-space: nowrap;
}

.capture-head select {
    -webkit-appearance: none;
    appearance: none;
    min-width: 240px;
    height: 48px;
    padding: 0 46px 0 18px;
    font-size: 16px;
    font-weight: 500;
    color: var(--ink);
    background-color: #fff;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235c6e78' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
    border: 1.5px solid var(--line-2);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(28, 43, 51, 0.05);
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
}
.capture-head select#subject_key {
    min-width: 180px;
}
.capture-head select:hover {
    border-color: var(--rise-line);
    background-color: #fffdf8;
}
.capture-head select.subj {
    background-color: var(--s-bg);
    border-color: var(--s-line);
    color: var(--s-ink);
    font-weight: 600;
}
.capture-head select.subj:hover {
    border-color: var(--s-ink);
}
.capture-head select:focus {
    border-color: var(--rise);
    box-shadow: 0 0 0 4px rgba(232, 147, 12, 0.16);
}
.capture-head select.subj:focus {
    border-color: var(--s-ink);
    box-shadow: 0 0 0 4px rgba(28, 43, 51, 0.08);
}
.capture-head select option {
    color: var(--ink);
    background: #fff;
    font-weight: 400;
}

.capture-head input[type="date"] {
    height: 48px;
    padding: 0 14px;
    font-size: 15.5px;
    border: 1.5px solid var(--line-2);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(28, 43, 51, 0.05);
    cursor: pointer;
}
.capture-head input[type="date"]:hover {
    border-color: var(--rise-line);
}

@media (max-width: 700px) {
    .capture-head select,
    .capture-head select#subject_key {
        min-width: 0;
        flex: 1 1 100%;
    }
    .capture-head .capture-date {
        margin-left: 0;
    }
}

/* ============================================================
   Subject wash — when a subject is picked, the page behind the cards
   glows in that subject's colour for about 2.5 seconds (18 Sept 2026).
   A fixed layer behind all content; clicks pass through it.
   ============================================================ */

.subject-wash {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0;
    background: var(--s-line, transparent);
}
.subject-wash.go {
    animation: subject-wash 2.6s ease-out forwards;
}
@keyframes subject-wash {
    0%   { opacity: 0; }
    12%  { opacity: 0.75; }
    45%  { opacity: 0.55; }
    100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .subject-wash.go {
        animation: none;
    }
}

/* ============================================================
   Save entry button (18 Sept 2026) — large, light, and in the chosen
   subject's colour once a subject is picked.
   ============================================================ */

button.save-entry {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 54px;
    padding: 0 32px 0 26px;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.01em;
    border-radius: 14px;
    border: 1.5px solid #efc47c;
    background: linear-gradient(180deg, #fff8ea 0%, #ffe9c4 100%);
    color: #8a5200;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 8px 18px -10px rgba(176, 110, 0, 0.55);
    transition: transform 0.12s ease, box-shadow 0.15s ease, filter 0.15s ease, border-color 0.15s ease;
}
button.save-entry svg {
    flex-shrink: 0;
}
button.save-entry:hover {
    background: linear-gradient(180deg, #fff8ea 0%, #ffe9c4 100%);
    border-color: #d99a34;
    color: #8a5200;
    filter: saturate(1.15);
    transform: translateY(-1px);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 12px 22px -10px rgba(176, 110, 0, 0.6);
}
button.save-entry:active {
    transform: translateY(0);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 4px 10px -6px rgba(176, 110, 0, 0.5);
}
button.save-entry:disabled {
    opacity: 0.6;
    cursor: wait;
    transform: none;
}

/* In the chosen subject's colour */
button.save-entry.subj,
button.save-entry.subj:hover {
    background: linear-gradient(180deg, var(--s-bg) 0%, var(--s-line) 100%);
    border-color: var(--s-ink);
    color: var(--s-ink);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 8px 18px -10px var(--s-ink);
}
button.save-entry.subj:hover {
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 12px 22px -9px var(--s-ink);
}

@media (max-width: 700px) {
    button.save-entry {
        width: 100%;
        justify-content: center;
    }
}

/* ============================================================
   Entry card, writing box and date in the chosen subject's colour
   (18 Sept 2026). Replaces the default amber edge and focus glow.
   ============================================================ */

.card.capture.open.subj {
    border-color: var(--s-line);
    box-shadow: var(--shadow), 0 0 0 4px var(--s-bg);
}
.capture textarea.subj {
    border-color: var(--s-line);
}
.capture textarea.subj:focus {
    border-color: var(--s-ink);
    box-shadow: 0 0 0 4px var(--s-line);
}
.capture-head input[type="date"].subj:hover {
    border-color: var(--s-line);
}
.capture-head input[type="date"].subj:focus {
    border-color: var(--s-ink);
    box-shadow: 0 0 0 4px var(--s-line);
}

/* ============================================================
   Symbol pad — "liquid glass" in the subject's colour (18 Sept 2026).
   Each group is a translucent tile with its label on top; keys are
   glossy chips set in a maths typeface.
   ============================================================ */

.symbol-pad.subj {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 10px;
    margin: 0 0 14px;
    padding: 12px;
    position: relative;
    overflow: hidden;
    border-radius: 18px;
    border: 1px solid var(--s-line);
    background:
        radial-gradient(120% 90% at 0% 0%, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0) 55%),
        radial-gradient(90% 80% at 100% 100%, color-mix(in srgb, var(--s-line) 70%, transparent) 0%, transparent 60%),
        linear-gradient(135deg, var(--s-bg) 0%, color-mix(in srgb, var(--s-line) 45%, white) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.95),
        inset 0 -1px 0 color-mix(in srgb, var(--s-line) 60%, transparent),
        0 12px 28px -20px var(--s-ink);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
}
.symbol-pad.subj[hidden] {
    display: none;
}

.symbol-pad.subj .symbol-group {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 10px 12px 12px;
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.72) 0%, rgba(255, 255, 255, 0.38) 100%);
    border: 1px solid rgba(255, 255, 255, 0.9);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 1),
        0 1px 2px color-mix(in srgb, var(--s-ink) 10%, transparent);
}

.symbol-pad.subj .symbol-group-label {
    margin: 0;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--s-ink);
    opacity: 0.85;
}

.symbol-pad.subj .symbol-keys {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

/* An odd last group spans the full width, so the grid has no hole. */
.symbol-pad.subj .symbol-group:last-child:nth-child(odd) {
    grid-column: 1 / -1;
}

.symbol-pad.subj .symbol-key {
    min-width: 40px;
    height: 38px;
    padding: 0 9px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--sans);
    font-size: 17px;
    font-weight: 600;
    line-height: 1;
    color: var(--s-ink);
    border-radius: 11px;
    border: 1px solid color-mix(in srgb, var(--s-line) 85%, white);
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 255, 255, 0.6) 55%, color-mix(in srgb, var(--s-bg) 80%, white) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 1),
        0 2px 5px -2px color-mix(in srgb, var(--s-ink) 35%, transparent);
    transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.symbol-pad.subj .symbol-key:hover {
    transform: translateY(-1px);
    border-color: var(--s-ink);
    background: linear-gradient(180deg, #fff 0%, var(--s-bg) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 1),
        0 6px 12px -6px color-mix(in srgb, var(--s-ink) 55%, transparent);
}
.symbol-pad.subj .symbol-key:active {
    transform: translateY(0);
    background: color-mix(in srgb, var(--s-line) 60%, white);
    box-shadow: inset 0 1px 3px color-mix(in srgb, var(--s-ink) 25%, transparent);
}
.symbol-pad.subj .symbol-key:focus-visible {
    outline: 2px solid var(--s-ink);
    outline-offset: 1px;
}

@media (max-width: 700px) {
    .symbol-pad.subj {
        grid-template-columns: 1fr;
    }
    .symbol-pad.subj .symbol-key {
        min-width: 44px;
        height: 42px;
    }
}

/* ============================================================
   Symbol pad toggle — a calculator button that opens the pad
   (18 Sept 2026). Glass chip in the subject's colour; filled when open.
   ============================================================ */

.pad-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 44px;
    margin: 14px 0 12px auto;
    padding: 0;
    border-radius: 13px;
    color: var(--s-ink, var(--ink-2));
    border: 1px solid var(--s-line, var(--line-2));
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, var(--s-bg, #fff) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 1),
        0 4px 10px -6px color-mix(in srgb, var(--s-ink, #1c2b33) 45%, transparent);
    transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.pad-toggle[hidden] {
    display: none;
}
.pad-toggle:hover {
    color: var(--s-ink, var(--ink));
    border-color: var(--s-ink, var(--ink-2));
    background: linear-gradient(180deg, #fff 0%, var(--s-line, #eee) 140%);
    transform: translateY(-1px);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 1),
        0 8px 16px -8px color-mix(in srgb, var(--s-ink, #1c2b33) 55%, transparent);
}
.pad-toggle.on {
    color: #fff;
    border-color: var(--s-ink);
    background: linear-gradient(180deg, color-mix(in srgb, var(--s-ink) 78%, white) 0%, var(--s-ink) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.35),
        0 8px 16px -8px var(--s-ink);
}
.pad-toggle:focus-visible {
    outline: 2px solid var(--s-ink, var(--rise));
    outline-offset: 2px;
}

/* In the tray's one-line boxes the button sits at the left, above the pad. */
.needs-detail .pad-toggle {
    margin: 8px 0 8px 0;
}

/* The entry form's calculator button sits in the subject row, beside the
   picker, matching the pickers' height (18 Sept 2026). */
.pad-toggle-slot {
    display: inline-flex;
}
.pad-toggle-slot:empty {
    display: none;
}
.capture-head .pad-toggle {
    width: 48px;
    height: 48px;
    margin: 0;
    border-radius: 12px;
}
.capture-head .pad-toggle:hover {
    transform: none;
}
.symbol-pad.subj#symbolPad {
    margin-top: 14px;
}
.capture textarea#capture {
    margin-top: 14px;
}
.symbol-pad.subj#symbolPad {
    margin-bottom: 0;
}

/* The mark beside the wordmark (18 Sept 2026). */
.wordmark {
    display: inline-flex;
    align-items: center;
}
.brand-mark {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    margin-right: 9px;
}

/* ============================================================
   Teacher dashboard (18 Sept 2026)
   Left: every topic of the subject, grouped by the class that teaches it,
   each group collapsible, each topic one bar — full green means the whole
   class has explained all of it, full blue means nobody has touched it.
   Right: the students, A to Z, in their own scrolling column.
   ============================================================ */

.dash {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 330px;
    gap: 18px;
    align-items: start;
    margin-bottom: 16px;
}
.dash-topics,
.dash-students {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 16px 18px;
    box-shadow: var(--shadow);
}
.dash-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.dash-head h3 {
    margin: 0;
    font-size: 16px;
}

.heat-legend {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    color: var(--ink-2);
    margin: 0 0 12px;
}
.bar-key {
    display: inline-block;
    width: 22px;
    height: 9px;
    border-radius: 3px;
    margin-left: 8px;
}
.bar-key.green { background: #2f8f5b; }
.bar-key.blue  { background: #8aa7c4; }

/* one expandable row per topic: the bar in the summary, the topic's own
   ideas inside, each with how many students have explained it */
h4.topic-heading {
    margin: 4px 0 6px;
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--s-ink, var(--ink-2));
}
details.topic-item {
    border-top: 1px solid var(--line);
}
details.topic-item > summary {
    display: grid;
    grid-template-columns: minmax(120px, 230px) minmax(0, 1fr) 132px;
    align-items: center;
    gap: 12px;
    padding: 9px 2px 9px 16px;
    cursor: pointer;
    position: relative;
    list-style: none;
}
details.topic-item > summary::-webkit-details-marker { display: none; }
details.topic-item > summary::before {
    content: '▸';
    position: absolute;
    left: 0;
    font-size: 11px;
    color: var(--ink-2);
}
details.topic-item[open] > summary::before { content: '▾'; }
details.topic-item[open] > summary { background: var(--s-bg, #fafbfc); }

details.earlier-topics {
    border-top: 1px solid var(--line);
    margin-top: 10px;
}
details.earlier-topics > summary {
    padding: 10px 2px;
    cursor: pointer;
    font-size: 14px;
    color: var(--ink-2);
}
details.earlier-topics > summary .small { color: var(--ink-2); }

ul.checkpoint-list {
    list-style: none;
    margin: 2px 0 12px;
    padding: 0 0 0 16px;
}
ul.checkpoint-list li {
    display: flex;
    gap: 10px;
    align-items: baseline;
    padding: 4px 0;
    font-size: 13.5px;
    border-bottom: 1px dashed var(--line);
}
ul.checkpoint-list li:last-child { border-bottom: none; }
ul.checkpoint-list li.none .cp-text { color: var(--ink-2); }
.cp-count {
    flex-shrink: 0;
    min-width: 42px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--s-ink, var(--ink));
}
ul.checkpoint-list li.none .cp-count { color: var(--ink-2); font-weight: 500; }
p.topic-detail { padding-left: 16px; color: var(--ink-2); }

.topic-name {
    font-size: 14px;
    color: var(--ink);
}
.topic-figure {
    color: var(--ink-2);
    text-align: right;
    white-space: nowrap;
}
.topic-bar {
    display: flex;
    height: 10px;
    border-radius: 999px;
    overflow: hidden;
    background: #eef2f5;
}
.topic-bar .green  { background: #2f8f5b; }
.topic-bar .blue   { background: #8aa7c4; }
.topic-bar .nolist { background: repeating-linear-gradient(45deg, #eef2f5 0 4px, #dfe6ec 4px 8px); }

/* the students, alphabetical, scrolling on their own */
.student-list {
    display: flex;
    flex-direction: column;
    gap: 9px;
    max-height: 70vh;
    overflow-y: auto;
    padding-right: 4px;
    scrollbar-width: thin;
    scrollbar-color: var(--line-2) transparent;
}
.student-card {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: 11px 13px;
    border-radius: 12px;
    border: 1px solid var(--s-line, var(--line-2));
    background: var(--s-bg, #fff);
    transition: border-color 0.15s ease, transform 0.12s ease;
}
.student-card:hover {
    border-color: var(--s-ink, var(--ink-2));
    transform: translateY(-1px);
}
.student-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
}
.student-head strong { font-size: 14.5px; }
.student-head em {
    color: var(--s-ink, var(--ink-2));
    font-style: normal;
}
.student-bar {
    margin: 8px 0 6px;
    height: 8px;
}
.student-foot { color: var(--ink-2); }

@media (max-width: 900px) {
    .dash { grid-template-columns: 1fr; }
    .student-list { max-height: none; }
    details.topic-item > summary { grid-template-columns: minmax(0, 1fr) 104px; }
    details.topic-item > summary .topic-bar { grid-column: 1 / -1; }
}
}

/* The column key above the student cards. */
.heat-key {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    color: var(--ink-2);
    margin: 0 0 12px;
}
.heat-key-item b {
    color: var(--ink);
}

/* A warning banner (a refused class, an account waiting for consent, a form
   that could not be saved). The colours already exist as variables. */
.banner.warn {
    background: var(--warn-bg);
    border-color: var(--warn);
    color: var(--warn);
}

/* Group colours: in Classes 6-10 a student picks Science or Social Science,
   not physics, so the group needs a tint of its own (18 Sept 2026). */
.subj-group-science        { --s-bg: #eef7f4; --s-line: #c6e4da; --s-ink: #1f7a63; }
.subj-group-social-science { --s-bg: #fbf5ea; --s-line: #ead9b6; --s-ink: #8a6220; }
.subj-group-mathematics    { --s-bg: #f2f4fc; --s-line: #d6dcf3; --s-ink: #3b4b9e; }

/* The teacher's "add a class" row: the fields and the button share one line
   and one height (18 Sept 2026). */
.class-form {
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
}
.class-form .field {
    margin: 0;
}
/* Narrower than the entry form's pickers, so subject, class, section and the
   button stay on one line with the Add class button beside them. */
.class-form select {
    min-width: 0;
    height: 48px;
}
.class-form select[name="subject_key"] {
    width: 215px;
}
.class-form select[name="class_level"] {
    width: 130px;
}
.class-form select[name="section"] {
    width: 132px;
}
.class-form .field > span {
    white-space: nowrap;
}
@media (min-width: 860px) {
    .class-form {
        flex-wrap: nowrap;
    }
}
button.add-class {
    height: 48px;
    white-space: nowrap;
    padding: 0 22px;
    font-size: 15px;
    font-weight: 600;
    border-radius: 12px;
    border: 1.5px solid var(--rise-line);
    background: linear-gradient(180deg, #fff8ea 0%, #ffe9c4 100%);
    color: #8a5200;
    transition: border-color 0.15s ease, filter 0.15s ease;
}
button.add-class:hover {
    border-color: var(--rise);
    background: linear-gradient(180deg, #fff8ea 0%, #ffe9c4 100%);
    color: #8a5200;
    filter: saturate(1.1);
}

/* Picking the subjects a teacher takes for one section: chips that toggle,
   shown once a class is chosen (18 Sept 2026). */
.class-row {
    margin-bottom: 4px;
}
.subject-pick {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}
.subject-pick > .small {
    width: 100%;
    color: var(--ink-2);
    margin-bottom: 2px;
}
label.subject-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border-radius: 999px;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    color: var(--s-ink, var(--ink));
    background: var(--s-bg, #fff);
    border: 1px solid var(--s-line, var(--line-2));
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
label.subject-chip:hover {
    border-color: var(--s-ink, var(--ink-2));
}
label.subject-chip:has(input:checked) {
    border-color: var(--s-ink);
    box-shadow: inset 0 0 0 1px var(--s-ink);
}
label.subject-chip input {
    accent-color: var(--s-ink, var(--rise));
    margin: 0;
}

/* The waiting screen a student sees until a parent consents (18 Sept 2026). */
.card.waiting h2 {
    margin-top: 0;
}
.card.waiting {
    border-left: 3px solid var(--rise);
}
.consent-page .card h2.sub {
    font-size: 15px;
    margin: 18px 0 6px;
    color: var(--ink);
}
.consent-choice {
    margin-top: 18px;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
}
ul.plain {
    margin: 4px 0 0;
    padding-left: 18px;
}

/* Each idea carries the class that teaches it, so a teacher can see at a
   glance which are this year's (18 Sept 2026). */
.cp-class {
    margin-left: auto;
    flex-shrink: 0;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}
ul.checkpoint-list li { justify-content: flex-start; }

/* A teacher's class list on their profile: the class, then a quiet Remove
   (18 Sept 2026). */
.class-line {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px dashed var(--line);
}
.class-line:last-of-type {
    border-bottom: none;
}
.class-line form {
    margin: 0;
}
/* ============================================================
   Writing notes — how the entry would read on an exam paper
   ============================================================
   Deliberately quiet. This is not a warning and must not look like one: no
   red, no icon, no border on the left the way an error has. The shelf bar is
   about what the learner understood; this is about how they wrote it, and the
   two are never mixed. */

.writenote {
    margin: 10px 0 0;
    padding: 10px 12px;
    background: #f7f7f5;
    border-radius: 8px;
    font-size: 0.88rem;
    color: #6b6f76;
}

.writenote-lead {
    margin: 0 0 6px;
    font-weight: 500;
    color: #5c6067;
}

.writenote ul {
    margin: 0;
    padding-left: 18px;
}

.writenote li {
    margin: 0 0 3px;
    line-height: 1.5;
}

.writenote-bit {
    font-family: var(--mono, ui-monospace, monospace);
    font-size: 0.85em;
    color: #8a8e97;
}

.writenote-foot {
    margin: 7px 0 0;
    font-size: 0.82rem;
    color: #9a9ea5;
}

/* The model's grammar suggestions sit under the punctuation notes, and are
   shown as a before and after because a corrected phrase teaches more than a
   rule about tense. Quieter still than the notes above them: these are the
   ones that can occasionally be wrong. */
.writenote-grammar {
    margin-top: 6px;
    background: #f5f6f8;
}

.writenote-was    { text-decoration: line-through; color: #9a9ea5; }
.writenote-arrow  { color: #b3b6bd; }
.writenote-better { color: #4a4e55; }

/* The part of a cumulative checklist earned at the learner's own class.
   Quieter than the headline count: it qualifies that number, it is not a
   second score (30 Sept 2026). */
.shelf-card .count.at-class {
    opacity: .72;
    font-size: .82em;
}

/* The teacher's topic list, this year's chapters first (1 Oct 2026). */
.topic-group-head { margin: 14px 0 6px; opacity: .75; }
.topic-earlier { margin-top: 14px; border-top: 1px solid var(--line, #e5e5e5); padding-top: 10px; }
.topic-earlier > summary { cursor: pointer; opacity: .7; padding: 4px 0; }
/* ============================================================
   Filing cards — "Is this the right topic?" (4 Oct 2026)
   One card per entry the classifier filed and the student has
   not yet checked. Same amber family as the new-shelf review
   banner, because it is the same kind of question.
   ============================================================ */

.filing-checks {
    margin: 18px 0 26px;
}

.filing-checks h2 {
    margin-bottom: 4px;
}

.filing-checks-note {
    color: var(--muted);
    margin: 0 0 10px;
}

.check-card {
    background: var(--rise-bg);
    border: 1px solid var(--rise-line);
    border-left: 4px solid var(--rise);
    border-radius: var(--radius-sm);
    padding: 14px 16px 14px 18px;
    margin: 10px 0;
}

.check-entry {
    margin: 0 0 8px;
    font-size: 15px;
    line-height: 1.55;
    color: var(--ink);
}

.check-where {
    margin: 0 0 12px;
    font-size: 14px;
    color: var(--ink-2);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px 8px;
}

.check-where a {
    color: var(--ink);
}

.check-new {
    font-size: 12px;
    font-weight: 600;
    padding: 1px 8px;
    border-radius: 999px;
    border: 1px solid var(--rise-line);
    background: var(--card);
    color: var(--ink-2);
}

.check-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.check-actions form {
    margin: 0;
}

.check-move {
    display: flex;
    gap: 8px;
    align-items: center;
    flex: 1;
    min-width: 260px;
    max-width: 520px;
}

.check-move select {
    flex: 1;
    min-width: 0;
}