/* ==========================================================================
   Aksh Niti - Concept & Formula Lab
   --------------------------------------------------------------------------
   Same visual language as Calc Lab, deliberately. That direction - the
   "Instrument" - was settled for this app and a second feature inventing its
   own would leave two design systems inside one product. So: the app's own
   tokens do the palette, three type roles, four material planes, three radii,
   one motion curve. What is different is the accent, a teal rather than Calc
   Lab's violet, so a learner can tell at a glance which tool they are in.

   THE HERO IS THE FORMULA. That is the one rule this file exists to enforce.
   Everything else on a card - the name, the legend chips, the reveal rows - is
   set smaller and quieter than the maths, because the maths is the thing being
   memorised. The failure mode being avoided is the one Calc Lab had before its
   redesign: the subject of the feature set in the body face at a body weight.

   Figures are styled here too, since they are inline SVG with classes rather
   than images. Their palette comes from the book - yellow, pink, orange fills
   with ink outlines - and swaps for dark theme in one place.
   ========================================================================== */

/* THE TOKENS AND THE OVERLAY ARE TWO DIFFERENT THINGS, and they were one
   rule until the notes page started rendering inside the app's own Notes
   screen. `.fl-scope` is the Lab's visual language with no layout attached:
   put it on any container and the .fl-* rules below work there. `.fl-backdrop`
   is that plus the full-screen overlay, and is still what the Lab itself uses.
   A token defined only on .fl-backdrop would resolve to nothing outside it —
   which is silent, because an undefined custom property just inherits. */
.fl-backdrop,
.fl-scope {
    --fl-accent: #45c4ad;
    --fl-accent-soft: rgba(69, 196, 173, 0.16);
    --fl-rail-w: 214px;

    /* ---- type: three roles ---------------------------------------------
       display  Archivo. The formula name, every number, card titles, buttons.
       data     JetBrains Mono. Working, typed answers, anything in a column.
       body     Inter. The prose is not the point.
       All three are already loaded by index.html for Calc Lab, so this adds
       no new network failure mode. */
    --fl-display: 'Archivo', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --fl-data: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* ---- material: four planes ------------------------------------------ */
    --fl-well: color-mix(in srgb, var(--app-bg) 88%, #000 12%);
    --fl-well-line: color-mix(in srgb, var(--line) 70%, transparent);
    --fl-inset: inset 0 1px 3px rgba(0, 0, 0, 0.45), inset 0 0 0 1px var(--fl-well-line);
    --fl-lift: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 28px rgba(0, 0, 0, 0.32);
    --fl-lift-hi: 0 2px 6px rgba(0, 0, 0, 0.4), 0 20px 52px rgba(0, 0, 0, 0.45);
    --fl-glow: 0 0 0 1px color-mix(in srgb, var(--fl-accent) 55%, transparent),
               0 6px 26px color-mix(in srgb, var(--fl-accent) 26%, transparent);

    /* ---- radius: the app's scale, three steps, no fourth ----------------- */
    --fl-r-lg: var(--radius, 20px);
    --fl-r: var(--radius-sm, 14px);
    --fl-r-sm: 10px;

    /* ---- motion: one curve ----------------------------------------------- */
    --fl-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --fl-fast: 0.14s;
    --fl-slow: 0.32s;

    /* ---- the book's figure palette ---------------------------------------
       Translucent in dark theme on purpose: a figure sits on the plain dark
       app background everywhere EXCEPT inside a filled shape, and every
       line/label color here (fl-fig-line, fl-fig-label) is the light theme
       text color, chosen for that dark background. An opaque light pastel
       fill fought that everywhere a chord/diagonal/guide line crossed
       through the shape's interior — light-on-light, invisible. Keeping the
       fill translucent lets the dark background show through enough that
       the same light line color still reads, without hunting down every
       line drawn over a fill and giving it a second, fill-specific color. */
    --fl-fig-yellow: rgba(247, 220, 122, 0.3);
    --fl-fig-pink: rgba(242, 169, 160, 0.3);
    --fl-fig-orange: rgba(238, 177, 115, 0.3);
    --fl-fig-ink: #10161f;
    --fl-fig-faint: rgba(255, 255, 255, 0.05);
    --fl-fig-label: var(--text-main, #e8eef8);
    --fl-fig-line: var(--text-main, #e8eef8);
}

.fl-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: var(--app-bg, #0c0f15);
    overscroll-behavior: contain;
    color: var(--text-main, #e8eef8);
}

html.theme-light .fl-backdrop,
html.theme-light .fl-scope {
    --fl-accent: #12897a;
    --fl-accent-soft: rgba(18, 137, 122, 0.10);
    --fl-well: #eef2f9;
    --fl-well-line: color-mix(in srgb, var(--line) 85%, transparent);
    --fl-inset: inset 0 1px 2px rgba(19, 26, 42, 0.07), inset 0 0 0 1px var(--fl-well-line);
    --fl-lift: 0 1px 2px rgba(19, 26, 42, 0.05), 0 8px 24px rgba(19, 26, 42, 0.07);
    --fl-lift-hi: 0 2px 6px rgba(19, 26, 42, 0.06), 0 18px 46px rgba(19, 26, 42, 0.11);
    --fl-fig-faint: rgba(19, 26, 42, 0.04);

    /* Light theme never had the contrast problem — fl-fig-line/label are
       dark text here, which already reads fine on both the plain light
       background and an opaque pastel fill. Keep these solid, book-accurate. */
    --fl-fig-yellow: #f7dc7a;
    --fl-fig-pink: #f2a9a0;
    --fl-fig-orange: #eeb173;
}

/* Everything that moves, moves on the same curve — or not at all. */
@media (prefers-reduced-motion: reduce) {
    .fl-backdrop,
    .fl-backdrop *,
    .fl-scope,
    .fl-scope * {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

.fl-backdrop,
.fl-backdrop *,
.fl-backdrop *::before,
.fl-backdrop *::after,
.fl-scope,
.fl-scope *,
.fl-scope *::before,
.fl-scope *::after { box-sizing: border-box; }

body.fl-open { overflow: hidden; }

/* ---------- shell -------------------------------------------------------- */

/* grid-template-rows is not optional. Without it the implicit row is `auto`,
   so the row grows to fit its content, .fl-main's height:100% resolves against
   that grown row, .fl-body never gets a bounded height, and it cannot scroll —
   while body.fl-open has already killed the page scroll behind it. Result: a
   long card is simply unreachable below the fold. The phone breakpoint had the
   right value all along, which is why only the desktop layout was stuck. */
.fl-page {
    display: grid;
    grid-template-columns: var(--fl-rail-w) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    height: 100%;
}

.fl-rail {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 16px 10px;
    /* Chrome sits BEHIND the content plane, not on it. */
    background: color-mix(in srgb, var(--app-bg) 82%, #000 18%);
    border-right: 1px solid var(--fl-well-line);
    overflow-y: auto;
}
html.theme-light .fl-rail { background: #e9eef6; }

.fl-rail-brand {
    display: flex; align-items: center; gap: 10px;
    background: none; border: 0; cursor: pointer; padding: 6px 8px 14px;
    text-align: left; color: inherit;
}
.fl-rail-mark {
    width: 34px; height: 34px; flex: none;
    display: grid; place-items: center;
    border-radius: var(--fl-r-sm);
    background: linear-gradient(140deg, var(--fl-accent), color-mix(in srgb, var(--fl-accent) 55%, #6d5cff));
    color: #04120f; font-size: 15px;
}
.fl-rail-name { font-family: var(--fl-display); font-weight: 800; font-size: 0.95rem; line-height: 1.1; }
.fl-rail-name small { display: block; font-weight: 500; font-size: 0.68rem; opacity: 0.6; }

.fl-rail-nav { display: flex; flex-direction: column; gap: 3px; }
.fl-rail-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 11px; border: 0; border-radius: var(--fl-r-sm);
    background: transparent; color: inherit; cursor: pointer;
    font-family: var(--fl-display); font-weight: 600; font-size: 0.84rem;
    transition: background var(--fl-fast) var(--fl-ease), color var(--fl-fast) var(--fl-ease);
}
.fl-rail-item i { width: 16px; text-align: center; opacity: 0.75; }
.fl-rail-item:hover { background: color-mix(in srgb, var(--fl-accent) 10%, transparent); }
.fl-rail-item.is-on {
    background: var(--fl-accent-soft);
    color: var(--fl-accent);
    box-shadow: inset 2px 0 0 var(--fl-accent);
}
.fl-rail-item.is-on i { opacity: 1; }

.fl-rail-foot { margin-top: auto; padding: 12px 10px 4px; display: flex; gap: 8px; flex-wrap: wrap; }
.fl-rail-stat {
    font-size: 0.7rem; opacity: 0.7; font-family: var(--fl-display);
}
.fl-rail-stat b { font-size: 0.9rem; opacity: 1; }
.fl-rail-stat.is-weak b { color: var(--danger, #ef6f6f); }

/* min-height: 0 for the same reason. A flex column child defaults to
   min-height:auto and refuses to shrink below its content, so .fl-body would
   push past the viewport instead of scrolling inside it. */
.fl-main {
    display: flex; flex-direction: column;
    min-width: 0; min-height: 0; height: 100%;
}

.fl-head {
    display: flex; align-items: center; gap: 12px;
    padding: 16px 22px;
    border-bottom: 1px solid var(--fl-well-line);
}
.fl-head-text { flex: 1; min-width: 0; }
.fl-head h2 {
    font-family: var(--fl-display); font-weight: 800;
    font-size: 1.22rem; margin: 0; line-height: 1.2;
}
.fl-head p { margin: 2px 0 0; font-size: 0.78rem; opacity: 0.62; }

/* The language chip. Two states shown at once so the learner can see which
   language is live and what the other one is, rather than pressing a toggle to
   find out. It flips the whole app's language, not a Lab-local one. */
.fl-lang {
    display: inline-flex; flex: none; padding: 3px; gap: 2px; cursor: pointer;
    border: 1px solid var(--fl-well-line); border-radius: 999px;
    background: var(--fl-well); color: inherit;
    font-family: var(--fl-display); font-weight: 700; font-size: 0.7rem;
}
.fl-lang span {
    padding: 3px 10px; border-radius: 999px; opacity: 0.45;
    transition: background var(--fl-fast) var(--fl-ease), opacity var(--fl-fast) var(--fl-ease);
}
.fl-lang span.is-on { background: var(--fl-accent); color: #04120f; opacity: 1; }

.fl-back, .fl-close {
    width: 36px; height: 36px; flex: none;
    border-radius: var(--fl-r-sm); border: 1px solid var(--fl-well-line);
    background: var(--fl-well); color: inherit; cursor: pointer;
    font-size: 1rem; line-height: 1;
    transition: background var(--fl-fast) var(--fl-ease), transform var(--fl-fast) var(--fl-ease);
}
.fl-back:hover, .fl-close:hover { background: var(--fl-accent-soft); transform: translateY(-1px); }
.fl-close { font-size: 1.4rem; }

.fl-body { flex: 1; overflow-y: auto; padding: 22px; }
.fl-col { max-width: 860px; margin: 0 auto; }

/* Sections enter staggered, so the screen reads as assembled rather than
   swapped. 40ms apart is the same rhythm Calc Lab uses. */
.fl-col > * { animation: fl-enter var(--fl-slow) var(--fl-ease) both; }
.fl-col > *:nth-child(2) { animation-delay: 0.04s; }
.fl-col > *:nth-child(3) { animation-delay: 0.08s; }
.fl-col > *:nth-child(4) { animation-delay: 0.12s; }
.fl-col > *:nth-child(n+5) { animation-delay: 0.16s; }

@keyframes fl-enter {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}

/* ---------- readout ------------------------------------------------------ */

.fl-readout {
    display: flex; align-items: center; gap: 22px;
    padding: 18px 20px; margin-bottom: 16px;
    border-radius: var(--fl-r-lg);
    background: var(--fl-well);
    box-shadow: var(--fl-inset);
}
.fl-readout.is-slim { padding: 14px 18px; }

.fl-ring { position: relative; width: 64px; height: 64px; flex: none; display: grid; place-items: center; }
.fl-ring svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.fl-ring-bg { fill: none; stroke: var(--fl-well-line); stroke-width: 6; }
.fl-ring-fg {
    fill: none; stroke: var(--fl-accent); stroke-width: 6; stroke-linecap: round;
    transition: stroke-dashoffset 0.8s var(--fl-ease);
}
.fl-ring-num {
    font-family: var(--fl-display); font-weight: 800; font-size: 1.05rem;
    font-variant-numeric: tabular-nums; line-height: 1;
}
.fl-ring-num small { font-size: 0.66rem; opacity: 0.55; font-weight: 600; }
.fl-ring-sub {
    position: absolute; bottom: -14px; left: 50%; transform: translateX(-50%);
    font-size: 0.6rem; opacity: 0.55; white-space: nowrap;
}

.fl-readout-cells { display: flex; gap: 26px; flex-wrap: wrap; }
.fl-cell b {
    display: block; font-family: var(--fl-display); font-weight: 800;
    font-size: 1.5rem; line-height: 1; font-variant-numeric: tabular-nums;
}
.fl-cell span { font-size: 0.7rem; opacity: 0.6; }
.fl-cell.is-warn b { color: var(--danger, #ef6f6f); }

/* ---------- hero cards & tiles ------------------------------------------- */

.fl-modes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 12px; }

.fl-mode {
    display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
    padding: 18px; text-align: left; cursor: pointer;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r-lg);
    background: var(--surface-solid, #141a24); color: inherit;
    box-shadow: var(--fl-lift);
    transition: transform var(--fl-slow) var(--fl-ease), box-shadow var(--fl-slow) var(--fl-ease);
}
.fl-mode:hover:not(.is-off) { transform: translateY(-3px); box-shadow: var(--fl-lift-hi); }
.fl-mode > i { font-size: 1.1rem; color: var(--fl-accent); margin-bottom: 4px; }
.fl-mode-t { font-family: var(--fl-display); font-weight: 800; font-size: 1rem; }
.fl-mode-b { font-size: 0.76rem; opacity: 0.6; line-height: 1.45; }
.fl-mode.is-off { opacity: 0.45; cursor: default; box-shadow: none; }

.fl-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 18px; }
.fl-tile {
    display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
    padding: 12px 14px; cursor: pointer; text-align: left;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--fl-well); color: inherit;
    transition: background var(--fl-fast) var(--fl-ease), transform var(--fl-fast) var(--fl-ease);
}
.fl-tile:hover { background: var(--fl-accent-soft); transform: translateY(-2px); }
.fl-tile i { color: var(--fl-accent); font-size: 0.9rem; }
.fl-tile b { font-family: var(--fl-display); font-size: 0.86rem; }
.fl-tile span { font-size: 0.68rem; opacity: 0.55; }

/* ---------- lists -------------------------------------------------------- */

.fl-h3 {
    font-family: var(--fl-display); font-weight: 800; font-size: 0.9rem;
    margin: 20px 0 8px; display: flex; align-items: center; gap: 8px;
}
.fl-col > .fl-h3:first-child { margin-top: 0; }
.fl-h3 span {
    font-size: 0.7rem; padding: 1px 8px; border-radius: 999px;
    background: var(--fl-well); opacity: 0.8;
}
.fl-why { font-size: 0.74rem; opacity: 0.58; margin: 0 0 8px; line-height: 1.5; }

.fl-chlist, .fl-flist { display: flex; flex-direction: column; gap: 6px; }

.fl-chrow, .fl-frow {
    position: relative; display: flex; align-items: center; gap: 12px;
    padding: 13px 16px; cursor: pointer; text-align: left; width: 100%;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--surface-solid, #141a24); color: inherit; overflow: hidden;
    transition: transform var(--fl-fast) var(--fl-ease), border-color var(--fl-fast) var(--fl-ease);
}
.fl-chrow:hover, .fl-frow:hover { transform: translateX(3px); border-color: var(--fl-accent); }

/* The progress bar IS the row's background, not a separate widget. */
.fl-chrow-bar {
    position: absolute; inset: 0 auto 0 0; width: var(--f, 0%);
    background: var(--fl-accent-soft); pointer-events: none;
    transition: width 0.7s var(--fl-ease);
}
.fl-chrow-name, .fl-chrow-n, .fl-chrow i { position: relative; }
.fl-chrow-name { flex: 1; font-family: var(--fl-display); font-weight: 700; font-size: 0.92rem; }
.fl-chrow-name small { display: block; font-weight: 500; font-size: 0.68rem; opacity: 0.5; }
.fl-chrow-n {
    font-family: var(--fl-display); font-weight: 800; font-size: 0.85rem;
    font-variant-numeric: tabular-nums; opacity: 0.7;
}
.fl-chrow > i.fa-chevron-right { font-size: 0.7rem; opacity: 0.4; }

.fl-frow-i {
    width: 22px; height: 22px; flex: none; display: grid; place-items: center;
    border-radius: 999px; background: var(--fl-well);
    font-family: var(--fl-display); font-size: 0.7rem; font-weight: 700; opacity: 0.7;
}
.fl-frow-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fl-frow-name { font-family: var(--fl-display); font-weight: 700; font-size: 0.88rem; }
.fl-frow-math { font-size: 0.9rem; opacity: 0.75; }
.fl-frow-ch { font-size: 0.68rem; opacity: 0.5; white-space: nowrap; }
.fl-frow-flag { color: var(--success, #4fd18b); }
.fl-frow.is-done { opacity: 0.65; }

/* The four weak states each get an edge, in the order they should worry you. */
.fl-frow.is-overconfident { box-shadow: inset 3px 0 0 #e0574f; }
.fl-frow.is-lapsed { box-shadow: inset 3px 0 0 #ef8f4f; }
.fl-frow.is-slow { box-shadow: inset 3px 0 0 #e4c15a; }
.fl-frow.is-flagged { box-shadow: inset 3px 0 0 var(--fl-accent); }
.fl-frow.is-untested { box-shadow: inset 3px 0 0 rgba(150, 160, 180, 0.7); }

.fl-pill {
    font-size: 0.64rem; font-weight: 700; padding: 2px 9px; border-radius: 999px;
    background: var(--fl-well); white-space: nowrap;
}
.fl-pill.is-overconfident { color: #e0574f; }
.fl-pill.is-lapsed { color: #ef8f4f; }
.fl-pill.is-slow { color: #e4c15a; }
.fl-pill.is-untested { opacity: 0.6; }

.fl-topics { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.fl-topic {
    display: flex; align-items: center; gap: 14px; padding: 14px;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--surface-solid, #141a24); color: inherit; cursor: pointer;
    box-shadow: var(--fl-lift);
    transition: transform var(--fl-slow) var(--fl-ease), box-shadow var(--fl-slow) var(--fl-ease);
}
.fl-topic:hover { transform: translateY(-3px); box-shadow: var(--fl-lift-hi); }
.fl-topic-t { font-family: var(--fl-display); font-weight: 800; font-size: 0.95rem; }
.fl-topic-t small { display: block; font-weight: 500; font-size: 0.66rem; opacity: 0.5; }

/* ---------- buttons ------------------------------------------------------ */

.fl-actions { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0; }
.fl-btn {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 10px 16px; cursor: pointer;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--fl-well); color: inherit;
    font-family: var(--fl-display); font-weight: 700; font-size: 0.84rem;
    transition: transform var(--fl-fast) var(--fl-ease), box-shadow var(--fl-fast) var(--fl-ease),
                background var(--fl-fast) var(--fl-ease);
}
.fl-btn:hover:not(:disabled) { transform: translateY(-2px); background: var(--fl-accent-soft); }
.fl-btn.is-primary {
    background: var(--fl-accent); border-color: transparent; color: #04120f;
    box-shadow: var(--fl-glow);
}
.fl-btn.is-primary:hover:not(:disabled) { background: var(--fl-accent); filter: brightness(1.06); }
.fl-btn.is-wide { flex: 1; justify-content: center; }
.fl-btn.is-sm { padding: 6px 11px; font-size: 0.74rem; }
.fl-btn:disabled, .fl-btn.is-off { opacity: 0.42; cursor: default; box-shadow: none; }

/* ---------- the card ----------------------------------------------------- */

.fl-card {
    padding: 20px 22px 8px;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r-lg);
    background: var(--surface-solid, #141a24);
    box-shadow: var(--fl-lift);
}

.fl-cardmeta { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.fl-tier {
    font-size: 0.62rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 999px; background: var(--fl-accent-soft); color: var(--fl-accent);
}
.fl-tier.is-extended { background: var(--fl-well); color: inherit; opacity: 0.7; }
.fl-tier.is-rare { background: var(--fl-well); color: inherit; opacity: 0.5; }
.fl-meta { font-size: 0.68rem; opacity: 0.5; font-variant-numeric: tabular-nums; }
.fl-flag {
    margin-left: auto; width: 32px; height: 32px; border-radius: var(--fl-r-sm);
    border: 1px solid var(--fl-well-line); background: var(--fl-well);
    color: inherit; cursor: pointer; opacity: 0.55;
    transition: opacity var(--fl-fast) var(--fl-ease), color var(--fl-fast) var(--fl-ease);
}
.fl-flag:hover { opacity: 1; }
.fl-flag.is-on { opacity: 1; color: var(--fl-accent); border-color: var(--fl-accent); }

/* Figure BESIDE the formula, not stacked above it. Read after the formula a
   diagram is a caption; read next to it, the labels in the drawing and the
   symbols in the formula are one glance apart — which is the whole reason
   mensuration is taught with pictures. Collapses to one column on phones,
   where two columns would leave both halves too narrow to read. */
.fl-cardmain { display: block; }
.fl-cardmain.has-fig {
    display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: 18px; align-items: center;
}
.fl-cardbody { min-width: 0; }
.fl-figwrap.is-side { margin: 0; }
.fl-figwrap.is-side .fl-fig { max-width: 100%; }

/* Row thumbnails. Big enough that the SHAPE is readable at a glance, because
   in mensuration the shape is how a formula is recognised - a 60px trapezium
   and a 60px parallelogram are the same grey wedge. */
.fl-figwrap.is-thumb { margin: 0; flex: none; width: 96px; }
.fl-figwrap.is-thumb .fl-fig { width: 96px; max-width: 96px; }
.fl-frow.has-fig { gap: 14px; padding: 16px 18px; }

/* ---------- shortcuts ----------------------------------------------------
   The one uncollapsed block on the card, and the one that must not read as
   prose. Each shortcut is a tile: a small accent trigger on top, the payload
   under it, an optional note beneath. The payload is typeset maths, a value
   strip or a ratio chain — never a sentence with an equation buried in it,
   which is what these looked like when they were bullets. */

.fl-cuts {
    margin: 16px 0 6px; padding: 14px 16px 16px;
    border-radius: var(--fl-r);
    background: color-mix(in srgb, var(--fl-accent) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--fl-accent) 28%, transparent);
}
.fl-cuts h4 {
    display: flex; align-items: center; gap: 7px; margin: 0 0 11px;
    font-family: var(--fl-display); font-weight: 800; font-size: 0.72rem;
    letter-spacing: 0.09em; text-transform: uppercase; color: var(--fl-accent);
}

.fl-cutgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }

.fl-cut {
    display: flex; flex-direction: column; gap: 5px;
    padding: 11px 13px; border-radius: var(--fl-r-sm);
    background: var(--surface-solid, #141a24);
    border: 1px solid var(--fl-well-line);
}
/* A sentence has no payload to line up beside, so it takes the full width
   rather than leaving half a tile of dead space next to it. */
.fl-cut.is-text { grid-column: 1 / -1; }

.fl-cut-when {
    font-family: var(--fl-display); font-weight: 700; font-size: 0.63rem;
    letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--fl-accent); opacity: 0.95;
}
.fl-cut-math { font-size: 1.02rem; }
.fl-cut-math .katex { font-size: 1.12em; }
.fl-cut-note { font-size: 0.72rem; opacity: 0.6; line-height: 1.55; }
.fl-cut-note.is-body { font-size: 0.8rem; opacity: 0.82; }

/* The ratio chain is the loudest thing in the block on purpose: 7 : 44 : 154
   is the single most useful line on a circle card. */
.fl-cut.is-ratio { justify-content: center; }
.fl-cut-is {
    font-family: var(--fl-display); font-weight: 800; font-size: 1.35rem;
    font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
    color: var(--fl-accent); line-height: 1.15;
}

/* Value strips are read like a table, so they get the data face and align. */
.fl-vstrip { display: flex; flex-wrap: wrap; gap: 5px; }
.fl-vpair {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 9px; border-radius: 999px;
    background: var(--fl-well); box-shadow: var(--fl-inset);
    font-family: var(--fl-data); font-size: 0.74rem;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.fl-vpair b { font-weight: 700; opacity: 0.75; }
.fl-vpair i { font-style: normal; opacity: 0.4; font-size: 0.7em; }

/* The hero. Everything else on the card is sized against this. A long
   multi-clause formula (several \qquad-separated results on one card) can
   render wider than the card — overflow-x here keeps that scroll contained
   to the box itself instead of pushing the whole page into horizontal
   scroll, which is what a bare grid with no width ceiling does by default. */
.fl-hero {
    display: grid; place-items: center;
    padding: 18px 14px; margin: 4px 0 14px;
    border-radius: var(--fl-r); background: var(--fl-well); box-shadow: var(--fl-inset);
    font-size: 1.35rem;
    max-width: 100%; overflow-x: auto;
}
.fl-hero .katex { font-size: 1.5em; }
.fl-hero.is-quiet { font-size: 1rem; opacity: 0.72; padding: 12px; }
.fl-hero.is-masked .katex { font-size: 1.6em; }

.fl-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.fl-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px; border-radius: 999px;
    background: var(--fl-well); border: 1px solid var(--fl-well-line);
    font-size: 0.74rem;
}
.fl-chip b { color: var(--fl-accent); font-weight: 700; }

.fl-conds {
    margin: 0 0 12px; padding: 8px 12px 8px 26px; list-style: disc;
    border-left: 2px solid var(--warning, #e4c15a);
    background: color-mix(in srgb, var(--warning, #e4c15a) 8%, transparent);
    border-radius: 0 var(--fl-r-sm) var(--fl-r-sm) 0;
    font-size: 0.76rem; line-height: 1.6;
}

/* Reveal rows. Closed by default on every render — see formulaLabUI's note. */
.fl-rows { display: flex; flex-direction: column; border-top: 1px solid var(--fl-well-line); }
.fl-row { border-bottom: 1px solid var(--fl-well-line); }
.fl-rowhead {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 12px 2px; border: 0; background: none; color: inherit; cursor: pointer;
    font-family: var(--fl-display); font-weight: 700; font-size: 0.82rem; text-align: left;
}
.fl-rowhead > i:first-child { color: var(--fl-accent); width: 15px; font-size: 0.8rem; }
.fl-rowhead span { flex: 1; }
.fl-rowcaret { font-size: 0.66rem; opacity: 0.5; transition: transform var(--fl-slow) var(--fl-ease); }
.fl-row.is-open .fl-rowcaret { transform: rotate(180deg); }

.fl-rowbody {
    display: grid; grid-template-rows: 0fr; opacity: 0;
    transition: grid-template-rows var(--fl-slow) var(--fl-ease), opacity var(--fl-slow) var(--fl-ease);
}
.fl-rowbody > * { overflow: hidden; }
.fl-row.is-open .fl-rowbody { grid-template-rows: 1fr; opacity: 1; }
.fl-rowbody p, .fl-rowbody ul, .fl-rowbody ol { font-size: 0.79rem; line-height: 1.65; margin: 0 0 10px; }

.fl-steps { padding-left: 20px; }
.fl-steps li { margin-bottom: 5px; }
.fl-traps { padding-left: 18px; color: var(--danger, #ef6f6f); }
.fl-src { opacity: 0.55; font-size: 0.74rem !important; }

.fl-rel { display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 10px; }
.fl-relbtn {
    padding: 5px 11px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--fl-well-line); background: var(--fl-well); color: inherit;
    font-size: 0.74rem;
}
.fl-relbtn:hover { border-color: var(--fl-accent); color: var(--fl-accent); }

/* ---------- figures ------------------------------------------------------ */

.fl-figwrap { display: grid; place-items: center; margin: 4px 0 12px; }
.fl-figwrap.is-small .fl-fig { max-width: 260px; }
.fl-fig { width: 100%; max-width: 380px; height: auto; overflow: visible; }

/* .fl-draw is declared BEFORE the fill classes and must stay there. A filled
   shape carries both classes - class="fl-fill-yellow fl-draw" - and the two
   selectors have identical specificity, so whichever is written last wins the
   `fill` declaration. With .fl-draw last, every polygon in the set silently
   lost its colour and rendered as a bare outline. */
.fl-fig .fl-draw { fill: none; stroke: var(--fl-fig-line); stroke-width: 2; stroke-linejoin: round; }
.fl-fig .fl-height { fill: none; stroke: var(--fl-accent); stroke-width: 2; stroke-dasharray: 5 4; }
.fl-fig .fl-fill-yellow { fill: var(--fl-fig-yellow); stroke: var(--fl-fig-line); stroke-width: 2; }
.fl-fig .fl-fill-pink { fill: var(--fl-fig-pink); stroke: var(--fl-fig-line); stroke-width: 2; }
.fl-fig .fl-fill-orange { fill: var(--fl-fig-orange); stroke: var(--fl-fig-line); stroke-width: 2; }
.fl-fig .fl-fill-faint { fill: var(--fl-fig-faint); stroke: var(--fl-well-line); stroke-width: 1.4; }
.fl-fig .fl-accent { stroke: var(--fl-accent); }
.fl-fig .fl-thick { stroke-width: 3.4; }
.fl-fig .fl-dash { stroke-dasharray: 6 4; }
.fl-fig .fl-guide { fill: none; stroke: var(--fl-fig-label); stroke-opacity: 0.4; stroke-width: 1.2; stroke-dasharray: 4 3; }
.fl-fig .fl-arc { fill: none; stroke: var(--fl-accent); stroke-width: 1.8; }
.fl-fig .fl-mark { fill: none; stroke: var(--fl-fig-line); stroke-width: 1.6; }
.fl-fig .fl-dim { stroke: var(--fl-fig-label); stroke-opacity: 0.55; stroke-width: 1.2; }
.fl-fig .fl-dim-head { fill: var(--fl-fig-label); fill-opacity: 0.55; }
.fl-fig .fl-dot { fill: var(--fl-fig-line); }
.fl-fig .fl-t {
    font-family: var(--fl-display); font-size: 13px; font-weight: 700;
    fill: var(--fl-fig-label); text-anchor: middle;
}
.fl-fig .fl-t-accent { fill: var(--fl-accent); }

/* Filled shapes sit on dark backgrounds, so their outlines are ink-dark and
   their labels are not — otherwise the label vanishes into the fill. */
.fl-backdrop .fl-fig .fl-fill-yellow,
.fl-backdrop .fl-fig .fl-fill-pink,
.fl-backdrop .fl-fig .fl-fill-orange { stroke: var(--fl-fig-ink); }

/* The one animation that is an explanation rather than decoration: the height
   drops onto the base, and the outline draws itself. */
.fl-fig .fl-draw {
    stroke-dasharray: 900;
    animation: fl-trace 0.75s var(--fl-ease) both;
}
.fl-fig .fl-height {
    transform-box: fill-box; transform-origin: top;
    animation: fl-drop 0.5s var(--fl-ease) 0.45s both;
}
@keyframes fl-trace { from { stroke-dashoffset: 900; } to { stroke-dashoffset: 0; } }
@keyframes fl-drop { from { transform: scaleY(0); opacity: 0; } to { transform: scaleY(1); opacity: 1; } }

/* ---------- session ------------------------------------------------------ */

.fl-prog {
    position: relative; display: flex; align-items: center; gap: 10px;
    padding: 9px 14px; margin-bottom: 12px;
    border-radius: var(--fl-r); background: var(--fl-well); box-shadow: var(--fl-inset);
    overflow: hidden;
}
.fl-prog-bar {
    position: absolute; inset: 0 auto 0 0; width: var(--f, 0%);
    background: var(--fl-accent-soft); transition: width var(--fl-slow) var(--fl-ease);
}
.fl-prog-txt, .fl-prog-score {
    position: relative; font-family: var(--fl-display); font-size: 0.76rem;
    font-variant-numeric: tabular-nums; font-weight: 700;
}
.fl-prog-score { margin-left: auto; opacity: 0.8; }
.fl-prog-score .is-ok { color: var(--success, #4fd18b); }
.fl-prog-score .is-bad { color: var(--danger, #ef6f6f); }

.fl-mixed {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 13px; margin: 0 0 12px; border-radius: var(--fl-r-sm);
    background: color-mix(in srgb, var(--fl-accent) 9%, transparent);
    border: 1px dashed color-mix(in srgb, var(--fl-accent) 40%, transparent);
    font-size: 0.73rem; opacity: 0.9;
}
.fl-mixed i { color: var(--fl-accent); }

.fl-qwrap { animation: fl-enter var(--fl-slow) var(--fl-ease) both; }

.fl-q {
    padding: 22px 20px; margin-bottom: 12px;
    border-radius: var(--fl-r-lg); background: var(--surface-solid, #141a24);
    border: 1px solid var(--fl-well-line); box-shadow: var(--fl-lift);
    text-align: center;
}
.fl-q-lead { font-size: 0.72rem; opacity: 0.55; margin: 0 0 6px; text-transform: uppercase; letter-spacing: 0.05em; }
.fl-q-name { font-family: var(--fl-display); font-weight: 800; font-size: 1.3rem; margin: 0 0 6px; }
.fl-q-name.is-sub { font-size: 0.95rem; opacity: 0.72; font-weight: 700; }
.fl-q-sit { font-size: 0.8rem; opacity: 0.6; margin: 0; }
.fl-q-ask { font-family: var(--fl-display); font-weight: 700; font-size: 1rem; margin: 8px 0 0; }

/* Same side-by-side idea inside a session: the figure and the thing being
   asked share a row rather than pushing the question off the fold. */
.fl-qmain {
    display: flex; align-items: center; justify-content: center;
    gap: 20px; flex-wrap: wrap;
}
.fl-qmain .fl-figwrap.is-side { flex: 0 1 300px; }
.fl-qmain .fl-hero { flex: 1 1 260px; margin: 0; }
.fl-qcol { flex: 1 1 260px; display: flex; flex-direction: column; gap: 10px; }
.fl-q.is-split { text-align: center; }

.fl-count {
    font-family: var(--fl-display); font-size: 1.05rem; color: var(--fl-accent);
}
.fl-practice .fl-actions { margin-bottom: 0; }

.fl-opts { display: grid; gap: 8px; }
.fl-opts.is-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.fl-opt {
    display: flex; align-items: center; gap: 12px; width: 100%;
    padding: 14px 16px; cursor: pointer; text-align: left;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--fl-well); color: inherit;
    transition: transform var(--fl-fast) var(--fl-ease), border-color var(--fl-fast) var(--fl-ease),
                background var(--fl-fast) var(--fl-ease);
}
.fl-opt:hover:not(:disabled) { transform: translateY(-2px); border-color: var(--fl-accent); }
.fl-opt-k {
    width: 24px; height: 24px; flex: none; display: grid; place-items: center;
    border-radius: 999px; background: color-mix(in srgb, var(--fl-accent) 16%, transparent);
    font-family: var(--fl-display); font-size: 0.7rem; font-weight: 800;
}
.fl-opt-v { flex: 1; font-size: 1.02rem; }
.fl-opt-v small { display: block; font-size: 0.68rem; opacity: 0.55; margin-top: 3px; }
.fl-opts.is-pair .fl-opt { flex-direction: column; text-align: center; padding: 20px 14px; }
.fl-opts.is-pair .fl-opt-v { font-size: 1.15rem; }

.fl-opt.is-right {
    border-color: var(--success, #4fd18b);
    background: color-mix(in srgb, var(--success, #4fd18b) 14%, transparent);
    animation: fl-pop 0.22s var(--fl-ease);
}
.fl-opt.is-wrong {
    border-color: var(--danger, #ef6f6f);
    background: color-mix(in srgb, var(--danger, #ef6f6f) 14%, transparent);
    animation: fl-shake 0.12s ease-in-out 2;
}
.fl-opt.is-dim { opacity: 0.4; }

@keyframes fl-pop { 0% { transform: scale(1); } 55% { transform: scale(1.025); } 100% { transform: scale(1); } }
@keyframes fl-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }

.fl-selfgrade { text-align: center; font-size: 0.76rem; opacity: 0.6; margin: 4px 0 8px; }
.fl-grades { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.fl-grade {
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    padding: 14px 8px; cursor: pointer;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--fl-well); color: inherit;
    font-family: var(--fl-display); font-weight: 700; font-size: 0.78rem;
    transition: transform var(--fl-fast) var(--fl-ease), border-color var(--fl-fast) var(--fl-ease);
}
.fl-grade:hover { transform: translateY(-2px); }
.fl-grade.is-yes:hover { border-color: var(--success, #4fd18b); color: var(--success, #4fd18b); }
.fl-grade.is-mid:hover { border-color: var(--warning, #e4c15a); color: var(--warning, #e4c15a); }
.fl-grade.is-no:hover { border-color: var(--danger, #ef6f6f); color: var(--danger, #ef6f6f); }

.fl-given {
    display: flex; flex-direction: column; gap: 3px; align-items: center;
    padding: 12px; border-radius: var(--fl-r-sm); background: var(--fl-well); box-shadow: var(--fl-inset);
}
.fl-given b { font-family: var(--fl-data); font-size: 1rem; }
.fl-given span { font-size: 0.76rem; opacity: 0.6; }

.fl-answer { display: flex; gap: 8px; margin-bottom: 10px; }
.fl-input {
    flex: 1; padding: 13px 16px;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r);
    background: var(--fl-well); color: inherit; box-shadow: var(--fl-inset);
    font-family: var(--fl-data); font-size: 1.05rem;
}
.fl-input:focus { outline: none; box-shadow: var(--fl-glow); border-color: transparent; }

.fl-verdict {
    display: flex; flex-direction: column; gap: 3px;
    padding: 13px 16px; border-radius: var(--fl-r); margin-bottom: 4px;
    animation: fl-pop 0.22s var(--fl-ease);
}
.fl-verdict.is-ok {
    background: color-mix(in srgb, var(--success, #4fd18b) 12%, transparent);
    box-shadow: inset 3px 0 0 var(--success, #4fd18b);
}
.fl-verdict.is-bad {
    background: color-mix(in srgb, var(--danger, #ef6f6f) 12%, transparent);
    box-shadow: inset 3px 0 0 var(--danger, #ef6f6f);
}
.fl-verdict b { font-family: var(--fl-display); font-size: 0.95rem; }
.fl-verdict span { font-size: 0.78rem; opacity: 0.75; }
.fl-working { font-family: var(--fl-data); font-size: 0.74rem !important; opacity: 0.6 !important; }

/* ---------- weak / sheets / empty ---------------------------------------- */

.fl-weakblock { margin-bottom: 18px; }
.fl-weakblock.is-overconfident .fl-h3 { color: #e0574f; }
.fl-weakblock.is-lapsed .fl-h3 { color: #ef8f4f; }
.fl-weakblock.is-slow .fl-h3 { color: #e4c15a; }

.fl-panel {
    padding: 16px 18px; margin-bottom: 12px;
    border: 1px solid var(--fl-well-line); border-radius: var(--fl-r-lg);
    background: var(--surface-solid, #141a24); box-shadow: var(--fl-lift);
}
.fl-panel .fl-h3:first-child { margin-top: 0; }
.fl-sheetrow {
    display: flex; align-items: center; gap: 8px; padding: 9px 0;
    border-top: 1px solid var(--fl-well-line);
}
.fl-sheetrow-n { flex: 1; font-family: var(--fl-display); font-weight: 700; font-size: 0.86rem; }

.fl-empty { text-align: center; padding: 46px 20px; }
.fl-empty i { font-size: 2rem; color: var(--fl-accent); opacity: 0.7; }
.fl-empty h3 { font-family: var(--fl-display); font-size: 1.05rem; margin: 12px 0 6px; }
.fl-empty p { font-size: 0.82rem; opacity: 0.6; max-width: 380px; margin: 0 auto 16px; line-height: 1.6; }

.fl-foot-note { font-size: 0.72rem; opacity: 0.45; line-height: 1.6; margin: 18px 0 40px; }

/* The same notes page, rendered inside the app's own Notes screen instead of
   inside the Lab's shell. Everything it needs from .fl-body/.fl-col — the
   measure and the padding — is restated here, and nothing else is, because
   the surrounding screen owns the scrolling and the background. */
.fl-embed { max-width: 860px; margin: 0 auto; padding: 4px 2px 0; }
.fl-embed .fl-toc { top: 4px; }
.fl-embed-head {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin: 0 0 4px;
    font-family: var(--fl-display); font-weight: 800; font-size: 1.05rem;
    color: var(--text-main, #e8eef8);
}

.fl-embed-head span {
    font-family: var(--fl-data); font-size: 0.72rem; opacity: 0.5;
    font-variant-numeric: tabular-nums;
}
.fl-embed > .fl-why { margin-bottom: 14px; max-width: 62ch; }

/* ---------- notes page ------------------------------------------------------
   The one screen in the Lab meant to be READ, so it is the one screen that
   uses the third type role for real: Inter at a comfortable measure, with the
   formula still set as the hero it is everywhere else. The visual language is
   unchanged - same wells, same three radii, same single motion curve - because
   this is another room in the same building, not a document viewer bolted on.
   -------------------------------------------------------------------------- */

/* Contents strip. Sticky because it is the only way back up a page that can
   run to eighty formulas; it sits under the header, which is why the offset
   is 0 - .fl-body is the scroller and the header is outside it. */
.fl-toc {
    position: sticky; top: 0; z-index: 2;
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    padding: 10px 12px; margin-bottom: 18px;
    border-radius: var(--fl-r); background: var(--fl-well);
    box-shadow: var(--fl-inset);
    backdrop-filter: blur(8px);
}
.fl-toc-label {
    font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em;
    opacity: 0.45; font-weight: 700; margin-right: 4px;
}
.fl-toc-link {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--fl-well-line); background: transparent; color: inherit;
    font-family: var(--fl-display); font-weight: 600; font-size: 0.74rem;
    transition: background var(--fl-fast) var(--fl-ease), border-color var(--fl-fast) var(--fl-ease);
}
.fl-toc-link:hover { background: var(--fl-accent-soft); border-color: var(--fl-accent); }
.fl-toc-link small {
    font-family: var(--fl-data); font-size: 0.64rem; opacity: 0.5;
    font-variant-numeric: tabular-nums;
}

.fl-notetopic { margin-bottom: 8px; scroll-margin-top: 64px; }
.fl-notetopic .fl-h3 { display: flex; align-items: center; gap: 10px; }
.fl-topicmap {
    width: 26px; height: 26px; flex: none; border-radius: var(--fl-r-sm);
    border: 1px solid var(--fl-well-line); background: var(--fl-well);
    color: inherit; cursor: pointer; opacity: 0.6; font-size: 0.7rem;
    transition: opacity var(--fl-fast) var(--fl-ease), color var(--fl-fast) var(--fl-ease);
}
.fl-topicmap:hover { opacity: 1; color: var(--fl-accent); border-color: var(--fl-accent); }

/* One formula as a note. Flat against the page rather than lifted like a
   card: on this screen they are paragraphs of one document, and twenty-seven
   floating cards in a column is a list, not a chapter. */
.fl-note {
    padding: 18px 0 20px;
    border-bottom: 1px solid var(--fl-well-line);
    scroll-margin-top: 64px;
}
.fl-note:last-child { border-bottom: 0; }

.fl-note-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.fl-note-i {
    flex: none; width: 26px; height: 26px; display: grid; place-items: center;
    border-radius: 999px; background: var(--fl-well); box-shadow: var(--fl-inset);
    font-family: var(--fl-data); font-size: 0.7rem; opacity: 0.65;
    font-variant-numeric: tabular-nums;
}
.fl-note-head h4 {
    flex: 1; min-width: 0; margin: 0;
    font-family: var(--fl-display); font-weight: 800; font-size: 1rem; line-height: 1.25;
}
/* Present but quiet. The reading page is not where a test is sold; this is
   here so that the moment a formula feels known, testing it is one tap away
   and not a scroll back to the chapter screen. */
.fl-note-open {
    flex: none; display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--fl-well-line); background: transparent; color: inherit;
    font-size: 0.7rem; opacity: 0.55;
    transition: opacity var(--fl-fast) var(--fl-ease), border-color var(--fl-fast) var(--fl-ease);
}
.fl-note-open:hover { opacity: 1; border-color: var(--fl-accent); color: var(--fl-accent); }

/* Smaller than the card screen's, and deliberately. One card gets a diagram
   the size of the formula beside it; twenty-seven in a column at that size is
   a gallery you scroll past, and the reading loses its line. */
.fl-note .fl-hero { font-size: 1.1rem; padding: 14px 12px; margin: 2px 0 12px; }
.fl-note .fl-figwrap.is-side .fl-fig { max-width: 250px; }

.fl-note-main { display: block; }
.fl-note-main.has-fig {
    display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: 18px; align-items: center;
}
.fl-note-body { min-width: 0; }

.fl-note-block { margin-bottom: 12px; }
.fl-note-block:last-child { margin-bottom: 0; }
.fl-note-block h5 {
    display: flex; align-items: center; gap: 7px; margin: 0 0 6px;
    font-family: var(--fl-display); font-weight: 700; font-size: 0.72rem;
    text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.5;
}
.fl-note-block h5 i { font-size: 0.7rem; opacity: 0.9; }
.fl-note-block p, .fl-note-block li { font-size: 0.82rem; line-height: 1.7; }
.fl-note-block p { margin: 0 0 8px; }
.fl-note-block > .fl-conds, .fl-note-block > .fl-chips { margin-bottom: 0; }

/* Colour lands in exactly three places on this page, as everywhere else in
   the Lab: the accent on the why, the warning on the conditions (which the
   shared .fl-conds already carries), and the danger on the traps. */
.fl-note-block.is-why h5 i { color: var(--fl-accent); }
.fl-note-block.is-ex h5 i { color: var(--fl-accent); opacity: 0.7; }
.fl-note-block.is-trap h5 { color: var(--danger, #ef6f6f); opacity: 0.75; }
.fl-note-block.is-trap .fl-traps { margin: 0; }

/* Shortcuts as a column. The label on the left says WHEN it applies and the
   shortcut itself sits in the well beside it, so the eye can run down the
   wells alone and skip the conditions on a second pass. */
.fl-note-block.is-cut h5 i { color: var(--fl-accent); }
.fl-note-cuts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.fl-note-cuts li {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px;
    padding: 8px 12px; border-radius: var(--fl-r-sm);
    background: var(--fl-well); box-shadow: var(--fl-inset);
}
.fl-note-cuts .fl-cut-when {
    flex: none; min-width: 96px; max-width: 220px;
    font-size: 0.7rem; opacity: 0.55; line-height: 1.45;
}
.fl-note-cut {
    flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    font-family: var(--fl-data); font-size: 0.82rem;
}
.fl-note-cut b { color: var(--fl-accent); font-weight: 700; }
.fl-note-cuts em {
    flex-basis: 100%; font-style: normal; font-size: 0.7rem; opacity: 0.5; line-height: 1.5;
}

/* ---------- book-page notes: every chapter --------------------------------
   A reading page should feel like a chapter in the source book, not a column
   of dashboard widgets. The paper is intentional even in dark theme: this is
   a separate document surface inside the Lab, while its controls remain live
   and the maths remains selectable. */
.fl-book-page {
    --fl-accent: #711f25;
    --fl-accent-soft: rgba(113, 31, 37, 0.09);
    --fl-well: #f7f0e5;
    --fl-well-line: #cbbba7;
    --surface-solid: #fffdf8;
    --warning: #b47a18;
    --danger: #8a2328;
    /* Notes are a light paper surface even when the app shell is dark.
       The default figure palette is intentionally light for that dark shell,
       so it must be reset here or labels / extension lines disappear. */
    --fl-fig-ink: #241b17;
    --fl-fig-line: #241b17;
    --fl-fig-label: #5e4034;
    --fl-fig-faint: rgba(94, 64, 52, 0.09);
    color: #251b18;
    padding: 18px;
    border: 1px solid #583330;
    background:
        linear-gradient(rgba(255, 253, 247, 0.96), rgba(255, 253, 247, 0.96)),
        repeating-linear-gradient(0deg, rgba(94, 60, 40, 0.025) 0 1px, transparent 1px 5px);
    box-shadow: 0 2px 20px rgba(0, 0, 0, 0.22);
}
.fl-book-page .fl-actions { margin: 16px 0; }
.fl-book-page .fl-btn,
.fl-book-page .fl-toc,
.fl-book-page .fl-topicmap { color: #251b18; }
.fl-book-page .fl-btn.is-primary { color: #fff9eb; background: #711f25; }
.fl-book-page .fl-toc { background: rgba(255, 253, 248, 0.92); }

.fl-book-intro { margin-bottom: 24px; border: 1px solid #39211e; background: #fffdf8; }
.fl-book-banner {
    position: relative; min-height: 92px; display: flex; align-items: center; gap: 16px;
    padding: 14px 28px 14px 0; overflow: hidden; background: #23090b; color: #fffaf1;
}
.fl-book-banner::after {
    content: ''; position: absolute; right: 0; bottom: 0; left: 158px; height: 8px;
    background: linear-gradient(90deg, #711f25 0 68%, #c68a2b 68% 78%, #711f25 78%);
}
.fl-book-chapter {
    z-index: 1; align-self: stretch; width: 95px; flex: none; display: grid; place-items: center;
    align-content: center; gap: 4px; background: #f0c05e; color: #241210;
    font-family: var(--fl-display); transform: skewX(-10deg);
}
.fl-book-chapter > * { transform: skewX(10deg); }
.fl-book-chapter small { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.08em; }
.fl-book-chapter b { display: grid; place-items: center; width: 38px; height: 38px; background: #711f25; color: #fffaf1; font-size: 1.25rem; }
.fl-book-ribbon { align-self: stretch; width: 19px; flex: none; margin-left: -5px; background: #8b451d; transform: skewX(-18deg); }
.fl-book-banner h2 { z-index: 1; margin: 0; font-family: var(--fl-display); font-size: clamp(1.75rem, 4vw, 2.65rem); font-weight: 800; letter-spacing: 0.02em; }
.fl-book-intro-generic { padding-bottom: 14px; }
.fl-book-generic-meta {
    display: inline-block; margin: 14px 20px 4px; padding: 5px 8px;
    border: 1px solid #b18c64; background: #f8ead7; color: #4b171a;
    font-family: var(--fl-data); font-size: 0.72rem; letter-spacing: 0.04em;
}
.fl-book-generic-meta b { margin-right: 5px; font-family: var(--fl-display); font-size: 0.68rem; }

.fl-book-perhundred {
    width: min(320px, 90%); margin: 18px auto; padding: 10px 14px 12px;
    display: grid; grid-template-columns: 1fr 26px 1fr; align-items: center; text-align: center;
    border: 1px solid #c78938; background: #f9d993; box-shadow: 4px 4px 0 rgba(113, 31, 37, 0.18);
    font-family: var(--fl-display); color: #3b1617;
}
.fl-book-perhundred b { font-size: 1.2rem; border-bottom: 2px solid #711f25; padding-bottom: 2px; }
.fl-book-perhundred span { font-size: 1.1rem; opacity: 0.55; }
.fl-book-perhundred strong { grid-column: 1 / -1; margin-top: 8px; font-size: 0.78rem; }
.fl-book-lead { margin: 0 20px 12px; font-size: 0.9rem; line-height: 1.75; }
.fl-book-tip {
    margin: 0 20px 16px; padding: 9px 12px; border-left: 4px solid #711f25;
    background: #f5e7c9; font-size: 0.82rem; line-height: 1.55;
}
.fl-book-tip i { color: #711f25; margin-right: 5px; }
.fl-book-table-wrap { margin: 0 20px 20px; border: 1px solid #4b2928; }
.fl-book-table-wrap h3 {
    margin: 0; padding: 9px 12px; background: #4b171a; color: #fff8ed;
    text-align: center; font-family: var(--fl-display); font-size: 1rem; letter-spacing: 0.03em;
}
.fl-book-table-scroll { overflow-x: auto; }
.fl-book-table { width: 100%; min-width: 560px; border-collapse: collapse; background: #fffdf8; text-align: center; }
.fl-book-table th, .fl-book-table td { padding: 7px 8px; border: 1px solid #9d8574; vertical-align: middle; }
.fl-book-table th { background: #734047; color: #fff9ec; font-family: var(--fl-display); font-size: 0.78rem; }
.fl-book-table td { font-family: var(--fl-data); font-size: 0.78rem; }
.fl-book-table td:nth-child(3), .fl-book-table th:nth-child(3) { border-right: 3px double #4b2928; }
.fl-book-table tbody tr:nth-child(even) { background: #fbf1e5; }
.fl-book-derived, .fl-book-worked { margin: 0 20px 20px; border: 1px solid #4b2928; background: #fffdf8; }
.fl-book-derived h3, .fl-book-worked h3 {
    margin: 0; padding: 9px 12px; background: #4b171a; color: #fff8ed;
    text-align: center; font-family: var(--fl-display); font-size: 0.92rem; letter-spacing: 0.03em;
}
.fl-book-derived table { width: 100%; border-collapse: collapse; }
.fl-book-derived th, .fl-book-derived td { padding: 7px 10px; border: 1px solid #b99d88; text-align: left; }
.fl-book-derived th { background: #734047; color: #fff8ed; font-family: var(--fl-display); font-size: 0.76rem; }
.fl-book-derived td { font-family: var(--fl-data); font-size: 0.75rem; line-height: 1.55; }
.fl-book-derived tbody tr:nth-child(even) { background: #fbf1e5; }
.fl-book-worked { border-color: #b18c64; }
.fl-book-worked h3 { background: #8b5528; }
.fl-book-worked-q {
    display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 10px; align-items: start;
    padding: 11px 12px; border-bottom: 1px dashed #cdb49c;
}
.fl-book-worked-q:last-child { border-bottom: 0; }
.fl-book-worked-q > span {
    display: grid; place-items: center; width: 25px; height: 25px; border-radius: 50%;
    background: #711f25; color: #fff8eb; font-family: var(--fl-data); font-size: 0.7rem; font-weight: 800;
}
.fl-book-worked-q b { display: block; font-size: 0.83rem; line-height: 1.5; }
.fl-book-worked-q code {
    display: block; margin-top: 5px; padding: 6px 8px; border-left: 3px solid #c68a2b;
    background: #fbf0da; color: #4b171a; font-family: var(--fl-data); font-size: 0.78rem; white-space: normal;
}

.fl-book-page .fl-notetopic { margin-bottom: 20px; }
.fl-book-page .fl-section-head {
    margin: 28px 0 10px; padding: 8px 12px; border-left: 6px solid #c68a2b;
    background: #f2e3cc; color: #4b171a; font-size: 1rem;
}
.fl-book-page .fl-book-note {
    position: relative; margin: 10px 0; padding: 18px 20px 20px 28px;
    border: 1px solid #cbbba7; border-radius: 0; background: #fffdf8;
    box-shadow: 2px 3px 0 rgba(78, 39, 34, 0.10);
}
.fl-book-page .fl-book-note::before {
    content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 6px; background: #711f25;
}
.fl-book-page .fl-note-i { border-radius: 0; background: #711f25; color: #fff8eb; box-shadow: none; opacity: 1; }
.fl-book-page .fl-note-head h4 { color: #4b171a; font-size: 1.08rem; }
.fl-book-page .fl-note .fl-hero { border: 1px solid #d1b789; background: #fff6df; box-shadow: none; }
/* Direct values here are intentional. Some SVG rules resolve their palette
   before the paper-sheet variables are inherited in the embedded Notes view. */
.fl-book-page .fl-fig .fl-draw,
.fl-book-page .fl-fig .fl-fill-yellow,
.fl-book-page .fl-fig .fl-fill-pink,
.fl-book-page .fl-fig .fl-fill-orange,
.fl-book-page .fl-fig .fl-mark { stroke: #241b17 !important; }
.fl-book-page .fl-fig .fl-fill-faint { stroke: #5e4034 !important; }
.fl-book-page .fl-fig .fl-guide,
.fl-book-page .fl-fig .fl-dim { stroke: #7a5545 !important; }
.fl-book-page .fl-fig .fl-dim-head,
.fl-book-page .fl-fig .fl-t { fill: #5e4034 !important; }
.fl-book-page .fl-fig .fl-t-accent { fill: #711f25 !important; }
.fl-book-page .fl-fig .fl-guide { stroke-opacity: 0.66; }
.fl-book-page .fl-fig .fl-dim { stroke-opacity: 0.75; }
.fl-book-page .fl-fig .fl-dim-head { fill-opacity: 0.75; }
.fl-book-page .fl-note-block.is-cut { padding: 10px 13px; border-top: 3px solid #711f25; background: #f8ead7; }
.fl-book-page .fl-note-cuts li { background: #fffdf8; box-shadow: none; border: 1px solid #decdbb; }
.fl-book-page .fl-foot-note { color: #5e4034; }

/* The source-book pattern: question, a small cue, written working and answer. */
.fl-book-solve { margin: 14px 0; border: 1px solid #b18c64; background: #fffdf8; }
.fl-book-solve > h5 {
    margin: 0; padding: 8px 11px; background: #4b171a; color: #fff8ed;
    font-family: var(--fl-display); font-size: 0.86rem; letter-spacing: 0.03em;
}
.fl-book-question, .fl-book-answer { padding: 9px 12px; }
.fl-book-question b, .fl-book-answer b { font-family: var(--fl-display); font-size: 0.76rem; letter-spacing: 0.04em; text-transform: uppercase; }
.fl-book-question p, .fl-book-answer p, .fl-book-hint p { margin: 4px 0 0; font-size: 0.84rem; line-height: 1.55; }
.fl-book-question { border-bottom: 1px solid #d7bf9f; background: #fff8ea; }
.fl-book-hint { margin: 10px 12px; padding: 8px 10px; border-left: 4px solid #c68a2b; background: #f7e6c4; }
.fl-book-hint b { color: #5f3219; font-family: var(--fl-display); font-size: 0.76rem; letter-spacing: 0.04em; }
.fl-book-solve-steps { margin: 10px 18px 12px 34px; padding: 0; }
.fl-book-solve-steps li { padding: 3px 0; font-size: 0.83rem; line-height: 1.55; }
.fl-book-answer { border-top: 1px dashed #b18c64; background: #fbf0da; color: #4b171a; }
.fl-book-answer b { color: #711f25; }

/* Book questions stay compact while every full method remains one click away. */
.fl-book-question-bank { margin: 28px 0 18px; border: 1px solid #4b2928; background: #fffdf8; }
.fl-book-question-bank > h3 {
    margin: 0; padding: 10px 13px; background: #4b171a; color: #fff8ed;
    font-family: var(--fl-display); font-size: 0.96rem; text-align: center;
}
.fl-book-question-bank > p { margin: 0; padding: 10px 13px; border-bottom: 1px solid #ddc8ad; background: #f8ead7; font-size: 0.8rem; line-height: 1.5; }
.fl-book-q { border-bottom: 1px solid #dfcbb3; }
.fl-book-q:last-child { border-bottom: 0; }
.fl-book-q summary { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 9px; align-items: start; padding: 10px 12px; cursor: pointer; list-style: none; }
.fl-book-q summary::-webkit-details-marker { display: none; }
.fl-book-q summary > span { display: grid; place-items: center; width: 24px; height: 24px; background: #711f25; color: #fff8eb; font-family: var(--fl-data); font-size: 0.7rem; font-weight: 800; }
.fl-book-q summary b { font-size: 0.82rem; line-height: 1.45; }
.fl-book-q summary small { padding-top: 3px; color: #76584a; font-family: var(--fl-data); font-size: 0.66rem; white-space: nowrap; }
.fl-book-q[open] summary { background: #fff4df; }
.fl-book-q-body { padding: 0 12px 12px 49px; }
.fl-book-q-body .fl-book-hint { margin: 0 0 8px; }
.fl-book-q-body .fl-book-solve-steps { margin-top: 7px; }
.fl-frac { display: inline-flex; flex-direction: column; align-items: stretch; justify-content: center; vertical-align: middle; min-width: 1.16em; margin: 0 0.08em; text-align: center; line-height: 0.76; font-family: var(--fl-data); font-size: 0.82em; }
.fl-frac sup, .fl-frac sub { display: block; padding: 0 0.12em; font-size: 1em; line-height: 0.9; }
.fl-frac i { display: block; flex: none; height: 1px; background: currentColor; margin: 0.11em 0 0.09em; }
.fl-book-table .fl-frac { transform: translateY(-0.02em); }
.fl-example-fig { max-width: 360px; margin: 12px auto 4px; padding: 6px; border: 1px dashed #b97b40; background: #fff8e9; border-radius: 8px; }
.fl-example-fig .fl-fig { display: block; width: 100%; height: auto; }
.fl-book-ratio-svg { display: block; width: min(250px, 100%); height: auto; margin: 9px auto 4px; overflow: visible; }
.fl-book-ratio-svg rect { fill: #fff7e8; stroke: #4b171a; stroke-width: 1.3; }
.fl-book-ratio-svg path { fill: none; stroke: #711f25; stroke-width: 1.6; }
.fl-book-ratio-svg marker path { fill: #711f25; stroke: none; }
.fl-book-ratio-svg text { fill: #4b171a; font-family: var(--fl-data); font-size: 10px; font-weight: 700; text-anchor: middle; }

@media (max-width: 640px) {
    .fl-book-page { padding: 10px; }
    .fl-book-banner { min-height: 74px; gap: 9px; padding-right: 12px; }
    .fl-book-banner::after { left: 106px; }
    .fl-book-chapter { width: 70px; }
    .fl-book-ribbon { width: 12px; }
    .fl-book-banner h2 { font-size: 1.6rem; }
    .fl-book-lead, .fl-book-tip, .fl-book-table-wrap, .fl-book-derived, .fl-book-worked { margin-left: 10px; margin-right: 10px; }
    .fl-book-page .fl-book-note { padding: 15px 13px 17px 20px; }
}

/* ---------- responsive ---------------------------------------------------- */

@media (max-width: 860px) {
    .fl-page { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
    .fl-rail {
        flex-direction: row; align-items: center; gap: 6px;
        padding: 8px 10px; border-right: 0; border-bottom: 1px solid var(--fl-well-line);
        overflow-x: auto; overflow-y: hidden;
    }
    .fl-rail-brand { padding: 0 8px 0 0; }
    .fl-rail-name small { display: none; }
    .fl-rail-nav { flex-direction: row; }
    .fl-rail-item { white-space: nowrap; }
    .fl-rail-item.is-on { box-shadow: inset 0 -2px 0 var(--fl-accent); }
    .fl-rail-foot { margin: 0 0 0 auto; padding: 0 4px; }

    .fl-body { padding: 14px; }
    .fl-modes, .fl-tiles { grid-template-columns: 1fr; }
    .fl-grades { grid-template-columns: 1fr; }
    .fl-opts.is-pair { grid-template-columns: 1fr; }
    .fl-readout { flex-direction: column; align-items: flex-start; gap: 18px; }
    .fl-head { padding: 12px 14px; }
    .fl-head h2 { font-size: 1.05rem; }
    .fl-hero { font-size: 1.15rem; }
    .fl-q-name { font-size: 1.1rem; }

    /* Two columns at phone width leaves the figure too small to read the
       labels off and the formula too narrow to set. One column, figure first. */
    .fl-cardmain.has-fig { grid-template-columns: 1fr; gap: 10px; }
    .fl-note-main.has-fig { grid-template-columns: 1fr; gap: 10px; }
    .fl-toc { padding: 8px; gap: 5px; }
    .fl-toc-label { display: none; }
    .fl-cutgrid { grid-template-columns: 1fr; }
    .fl-figwrap.is-thumb, .fl-figwrap.is-thumb .fl-fig { width: 72px; max-width: 72px; }
    .fl-frow.has-fig { gap: 10px; padding: 12px 14px; }
}
