/* Mistook: the design system.
 *
 * The idea is a notebook that has been marked up. Paper and ink do nearly all the work. Colour
 * comes in as four markers, and each one means something: the red pen (a mistake, and the brand),
 * the yellow highlighter (look here), the green felt-tip (right), the blue ballpoint (a link).
 * A wavy line is a word I am still unsure of, and it straightens as I learn it.
 *
 * The name is the method. I mistook a word, I retook it, and it took root. The face is in the
 * name: the two o's of "mistook" are its eyes. Things move the way a pen does: a line writes
 * itself, a mistake is struck through, a tick is drawn, and a word that is learned grows.
 *
 * Three layouts, not one stretched: a bar under the thumb on a phone, a rail on a tablet or a
 * narrow window, a sidebar with words on a laptop. The widths are Material's: 600, 840, 1200.
 *
 * Text is large on purpose. Size helps a slow reader more than any typeface does, lines stay
 * short, labels are never in capitals, and nothing is said in colour alone.
 */

/* ---- 1. Letters ---- */

@font-face { font-family: "Gabarito"; src: url(../fonts/Gabarito-normal-latin.woff2) format("woff2"); font-weight: 400 900; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Gabarito"; src: url(../fonts/Gabarito-normal-latin-ext.woff2) format("woff2"); font-weight: 400 900; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Atkinson Hyperlegible Next"; src: url(../fonts/AtkinsonHyperlegibleNext-normal-latin.woff2) format("woff2"); font-weight: 200 800; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Atkinson Hyperlegible Next"; src: url(../fonts/AtkinsonHyperlegibleNext-normal-latin-ext.woff2) format("woff2"); font-weight: 200 800; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Atkinson Hyperlegible Mono"; src: url(../fonts/AtkinsonHyperlegibleMono-normal-latin.woff2) format("woff2"); font-weight: 200 800; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Atkinson Hyperlegible Mono"; src: url(../fonts/AtkinsonHyperlegibleMono-normal-latin-ext.woff2) format("woff2"); font-weight: 200 800; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* ---- 2. Tokens ---- */

:root {
    /* Paper and ink. The paper is a little warm, which is easier on the eye than white. */
    --page: #f6f4ee;
    --paper: #fffefb;
    --sunken: #efece4;
    --line: #e6e2d8;
    --line-strong: #cdc7b9;
    --ink: #14162b;
    --ink-2: #454960;
    --ink-3: #65667a;

    /* The four markers, and an amber for "nearly" */
    --coral: #f2503e;
    --coral-soft: #ffe7e1;
    --yellow: #ffd84a;
    --yellow-soft: #fdf0b9;
    --green: #1f9d62;
    --green-soft: #dcf3e6;
    --blue: #2a3fef;
    --blue-soft: #e5e8fb;
    --amber: #c9770f;

    /* What they mean, in shades dark enough to read as text */
    --right: #116b3c;
    --right-bg: var(--green-soft);
    --close: #744d00;
    --close-bg: var(--yellow-soft);
    --wrong: #b32a18;
    --wrong-bg: var(--coral-soft);
    --link: #2536d6;

    --primary: var(--ink);
    --on-primary: #ffffff;
    --on-coral: #14162b;
    --on-yellow: #14162b;
    --focus: #2a3fef;

    /* The one dark card on a page */
    --hero: #14162b;
    --on-hero: #ffffff;

    /* Voices: one for titles and numbers, one for reading, one for spelling things out */
    --display: "Gabarito", "Atkinson Hyperlegible Next", system-ui, sans-serif;
    --text: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --letters: "Atkinson Hyperlegible Mono", ui-monospace, "Cascadia Mono", Menlo, monospace;

    /* Shape */
    --r-card: 20px;
    --r-control: 14px;
    --r-small: 10px;
    --shadow: 0 1px 2px rgba(20, 22, 43, .05), 0 8px 24px rgba(20, 22, 43, .07);
    --lift: 0 2px 6px rgba(20, 22, 43, .08), 0 18px 40px rgba(20, 22, 43, .16);

    /* Layout */
    --tabbar: 4rem;
    --rail: 5.4rem;
    --sidebar: 15.5rem;
    --reading: 42rem;
    --wide: 68rem;
    --gutter: 1rem;
    --prose: 62ch;

    /* Old names, kept so nothing written against them breaks */
    --bg: var(--page);
    --surface: var(--paper);
    --surface-2: var(--sunken);
    --border: var(--line);
    --text-dim: var(--ink-2);
    --text-faint: var(--ink-3);
    --accent: var(--ink);
    --accent-dim: var(--sunken);
    --on-accent: var(--on-primary);
    --good: var(--right);
    --good-bg: var(--right-bg);
    --radius: var(--r-card);
    --radius-sm: var(--r-control);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --page: #0f1124;
        --paper: #181b36;
        --sunken: #232750;
        --line: #2b2f58;
        --line-strong: #454a80;
        --ink: #eef0f8;
        --ink-2: #c0c4dc;
        --ink-3: #9a9fbf;

        --coral: #ff6a57;
        --coral-soft: #3b1d21;
        --yellow: #ffd84a;
        --yellow-soft: #3a3117;
        --green: #4fd08f;
        --green-soft: #143328;
        --blue: #8c9bff;
        --blue-soft: #222859;
        --amber: #f0a84a;

        --right: #6ee0a6;
        --close: #f2cb5c;
        --wrong: #ff9485;
        --link: #a9b3ff;

        --primary: #eef0f8;
        --on-primary: #14162b;
        --focus: #a9b3ff;

        --hero: #2a2f66;
        --on-hero: #ffffff;

        --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .3);
        --lift: 0 2px 6px rgba(0, 0, 0, .4), 0 18px 40px rgba(0, 0, 0, .5);
        color-scheme: dark;
    }
}

:root[data-theme="dark"] {
    --page: #0f1124;
    --paper: #181b36;
    --sunken: #232750;
    --line: #2b2f58;
    --line-strong: #454a80;
    --ink: #eef0f8;
    --ink-2: #c0c4dc;
    --ink-3: #9a9fbf;

    --coral: #ff6a57;
    --coral-soft: #3b1d21;
    --yellow: #ffd84a;
    --yellow-soft: #3a3117;
    --green: #4fd08f;
    --green-soft: #143328;
    --blue: #8c9bff;
    --blue-soft: #222859;
    --amber: #f0a84a;

    --right: #6ee0a6;
    --close: #f2cb5c;
    --wrong: #ff9485;
    --link: #a9b3ff;

    --primary: #eef0f8;
    --on-primary: #14162b;
    --focus: #a9b3ff;

    --hero: #2a2f66;
    --on-hero: #ffffff;

    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .3);
    --lift: 0 2px 6px rgba(0, 0, 0, .4), 0 18px 40px rgba(0, 0, 0, .5);
    color-scheme: dark;
}

/* ---- 3. Ground rules ---- */

* { box-sizing: border-box; }

/* Everything is in rem, so these three numbers scale the whole app. 18px to start with. */
html { font-size: 112.5%; color-scheme: light; -webkit-text-size-adjust: 100%; }
html[data-size="large"] { font-size: 125%; }
html[data-size="largest"] { font-size: 143.75%; }

body {
    margin: 0;
    font-family: var(--text);
    font-size: 1rem;
    line-height: 1.55;
    letter-spacing: .005em;
    background: var(--page);
    color: var(--ink);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--display); text-wrap: balance; letter-spacing: 0; }
h1 { font-size: 1.7rem; line-height: 1.12; font-weight: 800; margin: 0; }
h2 { font-size: 1.2rem; line-height: 1.2; font-weight: 700; margin: 1.6rem 0 .65rem; }
h3 { font-size: 1rem; line-height: 1.3; font-weight: 700; margin: 0 0 .4rem; color: var(--ink); }
p { margin: 0 0 .6rem; max-width: var(--prose); }

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: .18em; }

button, input, select, textarea { font: inherit; letter-spacing: inherit; }
select { color: var(--ink); }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 6px; }

/* The router moves focus to each page's heading for screen readers. It is not something to outline. */
h1:focus { outline: none; }

.icon { width: 1.35em; height: 1.35em; flex: 0 0 auto; display: inline-block; vertical-align: -.28em; }
.icon [data-f], .icon .f { fill: currentColor; stroke: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---- 4. The shell: three layouts ---- */

.shell { min-height: 100dvh; }

main { display: block; padding-bottom: calc(var(--tabbar) + env(safe-area-inset-bottom, 0px) + 1.25rem); }

/* Phone: a bar under the thumb. */
.tabbar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 20;
    height: calc(var(--tabbar) + env(safe-area-inset-bottom, 0px));
    padding: 0 .25rem env(safe-area-inset-bottom, 0px);
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    background: var(--paper);
    border-top: 1px solid var(--line);
}

.tabbar a {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .05rem;
    color: var(--ink-3);
    font-size: .78rem;
    font-weight: 700;
    text-decoration: none;
}

.tabbar a .icon { width: 1.5rem; height: 1.5rem; }
.tabbar a.active { color: var(--ink); padding-bottom: .55rem; }

/* The tab I am on gets the mark of the house: a short red squiggle. */
.tabbar a.active::after, .side-nav a.active::after {
    content: "";
    position: absolute;
    bottom: .5rem;
    width: 1.5rem;
    height: .4rem;
    background: var(--coral);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 7'%3E%3Cpath d='M2 4.500q2.750-4.500 5.500 0t5.500 0 5.500 0 5.500 0' fill='none' stroke='%23000' stroke-width='2.600' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 7'%3E%3Cpath d='M2 4.500q2.750-4.500 5.500 0t5.500 0 5.500 0 5.500 0' fill='none' stroke='%23000' stroke-width='2.600' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

.tabbar a.save { color: var(--ink); padding-bottom: 0; }
.tabbar a.save::after { display: none; }
.save-dot {
    width: 3.1rem;
    height: 3.1rem;
    margin-top: -1.2rem;
    border-radius: 50%;
    background: var(--coral);
    color: var(--on-coral);
    display: grid;
    place-items: center;
    box-shadow: 0 0 0 5px var(--page), var(--shadow);
}
.save-dot .icon { width: 1.6rem; height: 1.6rem; stroke-width: 2.6; }

/* Tablet, or a narrow window: the bar becomes a rail down the side. */
.side { display: none; }

@media (min-width: 600px) {
    .tabbar { display: none; }

    main { margin-left: var(--rail); padding-bottom: 2.5rem; }

    .side {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 20;
        width: var(--rail);
        display: flex;
        flex-direction: column;
        gap: .3rem;
        padding: .9rem .45rem;
        background: var(--paper);
        /* The margin line of a notebook page. */
        border-right: 2px solid var(--coral);
        overflow-y: auto;
        scrollbar-width: none;
    }

    .brand { display: grid; place-items: center; padding: .1rem 0 .7rem; color: var(--ink); text-decoration: none; }
    .brand .wordmark { display: none; }
    .brand .face { width: 2.5rem; height: 2.5rem; }

    .side-save {
        display: grid;
        place-items: center;
        flex: 0 0 auto;
        width: 3.1rem;
        height: 3.1rem;
        margin: 0 auto .7rem;
        border-radius: 50%;
        background: var(--coral);
        color: var(--on-coral);
        box-shadow: var(--shadow);
        text-decoration: none;
    }
    .side-save .label, .side-save kbd { display: none; }
    .side-save .icon { width: 1.6rem; height: 1.6rem; stroke-width: 2.6; }

    .side-nav { display: flex; flex-direction: column; gap: .1rem; }
    .side-nav .group { display: none; }

    .side-nav a {
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: .1rem;
        padding: .5rem .1rem .75rem;
        border-radius: var(--r-control);
        color: var(--ink-3);
        font-size: .76rem;
        font-weight: 700;
        text-align: center;
        line-height: 1.15;
        text-decoration: none;
    }

    .side-nav a .icon { width: 1.5rem; height: 1.5rem; }
    .side-nav a:hover { background: var(--sunken); color: var(--ink); text-decoration: none; }
    .side-nav a.active { color: var(--ink); }
    .side-nav a.active::after { bottom: .2rem; }
    .side-nav a .count { position: absolute; top: .2rem; right: .55rem; }

    /* The rail shows one door to practice. The sidebar shows the four rooms behind it instead. */
    .side-nav a.sub { display: none; }

    .side-foot { margin-top: auto; padding-top: .6rem; }
    .side-status { display: none; }
}

/* Laptop: the rail opens into a sidebar with words on it. */
@media (min-width: 1200px) {
    main { margin-left: var(--sidebar); }

    .side { width: var(--sidebar); padding: 1.1rem .8rem 1rem; gap: .15rem; }

    .brand { display: flex; align-items: center; gap: .5rem; justify-content: flex-start; padding: .1rem .55rem 1rem; }
    .brand:hover { text-decoration: none; }
    .brand .wordmark { display: block; }
    .brand .face { width: 2.1rem; height: 2.1rem; }

    .side-save {
        width: auto;
        height: 2.9rem;
        margin: 0 0 .8rem;
        border-radius: var(--r-control);
        display: flex;
        justify-content: flex-start;
        gap: .5rem;
        padding: 0 .85rem;
        font-weight: 700;
    }
    .side-save:hover { text-decoration: none; filter: brightness(1.05); }
    .side-save .label { display: inline; }
    .side-save kbd { display: inline-grid; margin-left: auto; background: rgba(20, 22, 43, .14); border: 0; color: inherit; }
    .side-save .icon { width: 1.3rem; height: 1.3rem; }

    .side-nav .group { display: block; margin: .9rem .7rem .25rem; font-size: .82rem; font-weight: 700; color: var(--ink-3); }

    .side-nav a, .side-nav a.sub {
        display: flex;
        flex-direction: row;
        gap: .65rem;
        min-height: 2.6rem;
        padding: 0 .7rem;
        font-size: 1rem;
        font-weight: 600;
        text-align: left;
        color: var(--ink-2);
    }

    .side-nav a .icon { width: 1.35rem; height: 1.35rem; }
    .side-nav a.active { background: var(--sunken); color: var(--ink); font-weight: 700; }
    .side-nav a.active::after { display: none; }
    .side-nav a.rail-only { display: none; }
    .side-nav a .count { position: static; margin-left: auto; }

    .side-status { display: flex; align-items: center; gap: .5rem; margin: .6rem .7rem 0; font-size: .82rem; color: var(--ink-3); }
    .side-status i { width: .55rem; height: .55rem; border-radius: 50%; background: var(--green); flex: 0 0 auto; }
    .side-status.off i { background: var(--ink-3); }
}

.count {
    display: inline-grid;
    place-items: center;
    min-width: 1.45rem;
    height: 1.45rem;
    padding: 0 .35rem;
    border-radius: 999px;
    background: var(--yellow);
    color: var(--on-yellow);
    font-size: .76rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* The name with the face in it: the two o's are the eyes, and the line under them is the mouth. */
.wordmark { display: inline-block; font-family: var(--display); font-weight: 800; font-size: 1.65rem; line-height: 1; letter-spacing: -.03em; color: var(--ink); white-space: nowrap; padding-bottom: .3em; }
.wm-eyes { position: relative; display: inline-block; }
/* A soft blink, so the name can always be read. */
.wm-oo { display: inline-block; transform-origin: 50% 64%; animation: blink-soft 6.4s infinite; }
.wm-mouth { position: absolute; left: 5%; width: 90%; top: .92em; overflow: visible; }
.wm-mouth path { fill: none; stroke: var(--coral); stroke-width: 3.6; stroke-linecap: round; stroke-linejoin: round; }
.wm-mouth.smile path { stroke: var(--green); }
.wm-mouth.rest path { stroke: var(--ink-3); }

kbd {
    display: inline-grid;
    place-items: center;
    min-width: 1.4rem;
    height: 1.4rem;
    padding: 0 .3rem;
    border-radius: 6px;
    border: 1px solid var(--line-strong);
    background: var(--paper);
    font-family: var(--text);
    font-size: .74rem;
    font-weight: 700;
    color: var(--ink-2);
}

/* ---- 5. A page ---- */

.page { max-width: var(--reading); margin: 0 auto; padding: 1.1rem var(--gutter) 1.5rem; }
.page.wide { max-width: var(--wide); }

@media (min-width: 600px) { :root { --gutter: 1.5rem; } .page { padding-top: 1.75rem; } }
@media (min-width: 1200px) { :root { --gutter: 2.25rem; } .page { padding-top: 2.25rem; } h1 { font-size: 2rem; } }

.page-head { margin-bottom: 1.15rem; }
.page-head .sub { font-size: 1rem; margin-top: .25rem; }
.sub { color: var(--ink-2); font-size: .92rem; }
.faint { color: var(--ink-3); }
.eyebrow { font-size: .86rem; font-weight: 700; color: var(--ink-3); }

.back, .btn.back {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: .25rem;
    min-height: 2.6rem;
    margin: -.5rem 0 .15rem -.15rem;
    padding: 0 .5rem 0 .1rem;
    border: 0;
    background: none;
    color: var(--ink-2);
    font-weight: 700;
    font-size: .95rem;
    text-decoration: none;
    cursor: pointer;
}
.back:hover, .btn.back:hover { color: var(--ink); background: none; text-decoration: none; }
.back .icon { width: 1.1rem; height: 1.1rem; }

/* One column on a phone, more when there is room. */
.stack { display: grid; gap: .8rem; align-content: start; }
.stack > *, .cols > * { min-width: 0; }
.cols { display: grid; gap: .8rem; align-items: start; }
.cols .card, .stack .card, .cols .fold, .stack .fold { margin-bottom: 0; }

@media (min-width: 840px) {
    .cols.main-side { grid-template-columns: minmax(0, 1.7fr) minmax(16.5rem, 1fr); gap: 1.4rem; }
    .cols.side-main { grid-template-columns: minmax(15rem, 20rem) minmax(0, 1fr); gap: 1.4rem; }
    .cols.halves { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.2rem; }
    .cols.thirds { grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.2rem; }
    .sticky { position: sticky; top: 1.5rem; }
}

/* A list beside what it lists: two panes when there is room, one at a time on a phone. */
.panes { display: grid; gap: 1.5rem; align-items: start; }
.panes > * { min-width: 0; }
.panes.showing-detail > .pane-list { display: none; }
.panes:not(.showing-detail) > .pane-detail { display: none; }
.pane-back { display: inline-flex; }

@media (min-width: 840px) {
    .panes { grid-template-columns: minmax(18rem, 23rem) minmax(0, 1fr); }
    .panes.showing-detail > .pane-list, .panes:not(.showing-detail) > .pane-detail { display: block; }
    .pane-detail { position: sticky; top: 1.5rem; max-height: calc(100dvh - 3rem); overflow-y: auto; scrollbar-width: thin; padding-right: .25rem; }
    .pane-back { display: none; }
}

/* ---- 6. Cards ---- */

.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    padding: 1.15rem;
    margin-bottom: .8rem;
}
.card.flush { padding: 0; overflow: hidden; }
.card-link { display: block; color: inherit; text-decoration: none; }
a.card.card-link:hover { text-decoration: none; border-color: var(--line-strong); }
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
.card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-bottom: .6rem; }
.card-head h3 { margin: 0; }
.card-head a { font-weight: 700; font-size: .92rem; }

/* The one thing to do now: ink on the page, like a sticker. */
.hero {
    position: relative;
    overflow: hidden;
    background: var(--hero);
    color: var(--on-hero);
    border-radius: var(--r-card);
    padding: 1.35rem 1.25rem 1.3rem;
    margin-bottom: .8rem;
}
.cols .hero, .stack .hero { margin-bottom: 0; }
.hero .eyebrow { color: var(--yellow); }
.hero h2, .hero .hero-title { font-family: var(--display); font-size: 1.55rem; line-height: 1.15; margin: .15rem 0 .2rem; font-weight: 800; }
.hero .sub { color: inherit; opacity: .8; font-size: 1rem; }
.hero .hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: 1.1rem; }
.hero .hero-face { display: none; position: absolute; right: 1.3rem; top: 1.15rem; width: 4.6rem; height: 4.6rem; color: var(--on-hero); }
.hero .btn-primary { background: var(--yellow); border-color: var(--yellow); color: var(--on-yellow); min-width: 9rem; }
.hero .btn-primary:hover { background: color-mix(in srgb, var(--yellow) 88%, #fff); }
.hero .btn:not(.btn-primary) { background: transparent; color: inherit; border-color: color-mix(in srgb, currentColor 40%, transparent); }
.hero .chip { background: transparent; color: inherit; border-color: color-mix(in srgb, currentColor 38%, transparent); }
.hero .chip:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
.hero .face .mouth { stroke: var(--coral); }
.hero .face.smile .mouth { stroke: var(--yellow); }
@media (min-width: 600px) { .hero .hero-face { display: block; } .hero { padding: 1.6rem 1.6rem 1.5rem; } .hero h2, .hero .hero-title { font-size: 1.85rem; padding-right: 5.5rem; } }

/* ---- 7. Buttons ---- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    min-height: 2.9rem;
    padding: 0 1.1rem;
    border: 1.5px solid var(--line-strong);
    border-radius: var(--r-control);
    background: var(--paper);
    color: var(--ink);
    font: inherit;
    font-weight: 700;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: background .14s ease, border-color .14s ease, box-shadow .14s ease, transform .14s cubic-bezier(.2, .8, .2, 1);
}
.btn:hover { background: var(--sunken); text-decoration: none; }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .45; cursor: default; }
.btn .icon { width: 1.25em; height: 1.25em; }

.btn-primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.btn-primary:hover { background: color-mix(in srgb, var(--primary) 86%, var(--paper)); }
.btn-coral { background: var(--coral); border-color: var(--coral); color: var(--on-coral); }
.btn-coral:hover { background: color-mix(in srgb, var(--coral) 90%, #fff); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--link); padding: 0 .7rem; }
.btn-ghost:hover { background: var(--blue-soft); }
.btn-lg { min-height: 3.4rem; padding: 0 1.5rem; font-family: var(--display); font-size: 1.15rem; border-radius: 16px; }
.btn-block { width: 100%; }
.btn-row { display: flex; gap: .5rem; flex-wrap: wrap; }

/* A button never stretches across a wide page. */
@media (min-width: 840px) { .page > .btn-block, .page-actions .btn-block { max-width: 24rem; } }

/* An icon alone, still large enough for a thumb. */
.btn.hear-small, .icon-btn { min-height: 2.75rem; min-width: 2.75rem; padding: 0; flex: 0 0 auto; border-radius: 50%; }

.link {
    background: none;
    border: 0;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    min-height: 2.6rem;
    padding: .2rem .1rem;
    color: var(--link);
    font: inherit;
    font-weight: 700;
    font-size: .95rem;
    cursor: pointer;
}
.link:hover { text-decoration: underline; text-underline-offset: .18em; }
.link:disabled { opacity: .5; cursor: default; }

/* ---- 8. Inputs ---- */

.field { width: 100%; }

.input {
    width: 100%;
    min-height: 3.1rem;
    padding: .6rem .9rem;
    border: 1.5px solid var(--line-strong);
    border-radius: var(--r-control);
    background: var(--paper);
    color: var(--ink);
    font: inherit;
    font-size: 1.05rem;
}
.input::placeholder { color: var(--ink-3); }
.input:focus { outline: none; border-color: var(--focus); box-shadow: 0 0 0 4px color-mix(in srgb, var(--focus) 20%, transparent); }
textarea.input { min-height: 11rem; resize: vertical; line-height: 1.6; }

/* Where a word is spelled out: the letters face, large and well spaced. */
.input-answer { font-family: var(--letters); font-size: 1.65rem; font-weight: 600; text-align: center; letter-spacing: .05em; min-height: 4.1rem; }
.input.is-right { border-color: var(--green); background: var(--right-bg); color: var(--right); }
.btn.is-right, .btn.is-right:disabled { background: var(--green); border-color: var(--green); color: #fff; opacity: 1; }

label.lbl, div.lbl { display: block; font-size: .95rem; font-weight: 700; color: var(--ink-2); margin-bottom: .35rem; }
label.check { display: flex; align-items: center; gap: .65rem; min-height: 2.75rem; cursor: pointer; }
label.check input { width: 1.3rem; height: 1.3rem; flex: 0 0 auto; accent-color: var(--ink); }

.search { position: relative; }
.search > .icon { position: absolute; left: .85rem; top: 50%; transform: translateY(-50%); color: var(--ink-3); width: 1.25rem; height: 1.25rem; pointer-events: none; }
.search .input { padding-left: 2.7rem; }

.capture-ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr)); gap: .5rem; margin-top: .6rem; }
.capture-links { display: flex; justify-content: space-between; flex-wrap: wrap; gap: .25rem 1rem; margin-top: .25rem; }

/* ---- 9. Chips and tags ---- */

.chips { display: flex; flex-wrap: wrap; gap: .4rem; padding: .1rem 0 .5rem; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 2.6rem;
    padding: 0 .95rem;
    border: 1.5px solid var(--line-strong);
    border-radius: 999px;
    background: var(--paper);
    color: var(--ink-2);
    font: inherit;
    font-size: .92rem;
    font-weight: 700;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
}
.chip:hover { background: var(--sunken); text-decoration: none; }
.chip.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.tag {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .12rem .6rem;
    margin: .1rem .15rem .1rem 0;
    border-radius: 999px;
    background: var(--sunken);
    color: var(--ink-2);
    font-size: .84rem;
    font-weight: 700;
    white-space: nowrap;
}
.tag-good { background: var(--right-bg); color: var(--right); }
.tag-close { background: var(--close-bg); color: var(--close); }
.tag-wrong { background: var(--wrong-bg); color: var(--wrong); }
.tag-due { background: var(--yellow); color: var(--on-yellow); }

/* ---- 10. Lists ---- */

.list { list-style: none; margin: 0; padding: 0; }
.list li + li { border-top: 1px solid var(--line); }

.row { display: flex; align-items: center; gap: .8rem; padding: .85rem 1.1rem; color: inherit; text-decoration: none; }
a.row:hover, button.row:hover { background: var(--sunken); text-decoration: none; }
.row .grow, .grow { flex: 1; min-width: 0; }
.row .ttl { font-weight: 700; line-height: 1.3; }
.row .meta { font-size: .9rem; line-height: 1.35; color: var(--ink-2); margin-top: .1rem; }
.row .chev, .chev { color: var(--ink-3); flex: 0 0 auto; font-size: 1.3rem; line-height: 1; }
.row.plain { width: 100%; background: none; border: 0; font: inherit; text-align: left; cursor: pointer; }
.row.on { background: var(--sunken); box-shadow: inset 3px 0 0 var(--coral); }

/* A picture beside a row: an icon on a soft square of one of the markers. */
.pic {
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 14px;
    display: grid;
    place-items: center;
    background: var(--sunken);
    color: var(--ink);
}
.pic .icon { width: 1.5rem; height: 1.5rem; }
.pic.spelling { background: var(--yellow-soft); }
.pic.speaking { background: var(--coral-soft); }
.pic.readwrite { background: var(--blue-soft); }
.pic.play { background: var(--green-soft); }

/* A grid of things to do, each with its picture. */
.feature-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(15.5rem, 100%), 1fr)); gap: .7rem; }
.feature {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: .85rem;
    align-items: center;
    padding: .95rem 1.05rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.feature:hover { border-color: var(--line-strong); text-decoration: none; }
.feature .pic { grid-row: span 2; width: 3rem; height: 3rem; }
.feature .ttl { font-weight: 700; line-height: 1.25; align-self: end; }
.feature .meta { font-size: .9rem; color: var(--ink-2); line-height: 1.3; align-self: start; }
.feature .ttl:last-child { grid-row: span 2; align-self: center; }

/* The five big doors on the phone's More page. */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; }
.tile-big {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    gap: .9rem;
    min-height: 7.5rem;
    padding: 1rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    color: inherit;
    text-decoration: none;
}
.tile-big:hover { text-decoration: none; border-color: var(--line-strong); }
.tile-big:last-child:nth-child(odd) { grid-column: 1 / -1; min-height: 0; flex-direction: row; align-items: center; justify-content: flex-start; }
.tile-big .pic { width: 3.2rem; height: 3.2rem; }
.tile-big .pic .icon { width: 1.7rem; height: 1.7rem; }
.tile-big .ttl { font-family: var(--display); font-weight: 700; font-size: 1.2rem; line-height: 1.2; }

/* A word in my list: the word, how it breaks, and the line that shows how sure I am of it. */
.word-row .word { font-weight: 700; font-size: 1.1rem; line-height: 1.25; overflow-wrap: anywhere; }
.word-row .split { font-family: var(--letters); font-size: .86rem; color: var(--ink-2); }

.stage-line { flex: 0 0 auto; width: 3.4rem; height: .85rem; display: inline-block; }
.stage-line path { fill: none; stroke-width: 3.6; stroke-linecap: round; stroke-linejoin: round; }
.stage-line.s1 path { stroke: var(--coral); }
.stage-line.s2 path { stroke: var(--amber); }
.stage-line.s3 path { stroke: var(--blue); }
.stage-line.s4 path { stroke: var(--green); }
.stage-line.s0 path { stroke: var(--line-strong); }

.stage-rows { display: grid; gap: .05rem; }
.stage-row { display: flex; align-items: center; gap: .8rem; min-height: 2.2rem; }
.stage-row .grow { color: var(--ink-2); font-weight: 600; }
.stage-row strong { font-family: var(--display); font-size: 1.15rem; font-variant-numeric: tabular-nums; }

/* What I got wrong, and what it should be. */
.fixes { display: grid; }
.fix { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; padding: .45rem 0; color: inherit; font-family: var(--letters); font-size: 1rem; border-top: 1px solid var(--line); }
.fix:first-child { border-top: 0; }
a.fix:hover { text-decoration: none; background: var(--sunken); }
.fix s { color: var(--wrong); text-decoration-thickness: .1em; }
.fix b { font-weight: 700; }
.fix b::before { content: "→ "; color: var(--ink-3); font-weight: 400; }

/* ---- 11. Notices and empty screens ---- */

.notice {
    padding: .75rem .95rem;
    border-radius: var(--r-control);
    background: var(--sunken);
    color: var(--ink-2);
    font-size: .96rem;
    margin-bottom: .8rem;
}
.notice > .icon:first-child { margin-right: .4rem; }
.notice a { font-weight: 700; }
.notice .link { min-height: 0; padding: 0 .1rem; vertical-align: baseline; }
.notice-good { background: var(--right-bg); color: var(--right); }
.notice-wrong { background: var(--wrong-bg); color: var(--wrong); }
.notice-info { background: var(--blue-soft); color: var(--ink); }
.notice-tip { background: var(--yellow-soft); color: var(--ink); }

.empty { text-align: center; padding: 2.5rem 1rem; color: var(--ink-2); display: grid; justify-items: center; gap: .5rem; }
.empty p { margin: 0; }
.empty strong { font-family: var(--display); font-size: 1.25rem; color: var(--ink); }
.empty .face { width: 5.5rem; height: 5.5rem; color: var(--ink); margin-bottom: .3rem; }
.empty .big { width: 4.5rem; height: 4.5rem; border-radius: 50%; background: var(--sunken); color: var(--ink); display: grid; place-items: center; margin-bottom: .3rem; }
.empty .big .icon { width: 2.1rem; height: 2.1rem; }
.empty .btn-row { justify-content: center; margin-top: .5rem; }

/* The one honest line when the laptop does not answer. */
.laptop-line {
    position: sticky;
    top: 0;
    z-index: 15;
    padding: .5rem 1rem;
    background: var(--yellow-soft);
    color: var(--ink);
    font-size: .95rem;
    font-weight: 600;
    text-align: center;
    border-bottom: 1px solid var(--line);
}

/* ---- 12. The face ---- */

.face { display: block; }
.face .eye, .face .mouth { fill: none; stroke-width: 4.6; stroke-linecap: round; stroke-linejoin: round; }
.face .eye { stroke: currentColor; }
.face .mouth { stroke: var(--coral); }
.face.smile .mouth { stroke: var(--green); }
.face.steady .mouth { stroke: var(--amber); }
.face.listen .mouth { stroke: var(--blue); }
.face.rest .mouth { stroke: var(--ink-3); }

/* ---- 13. Numbers and progress ---- */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(5.2rem, 1fr)); gap: .6rem; }
.stat { background: var(--paper); border: 1px solid var(--line); border-radius: 16px; padding: .8rem .4rem .7rem; text-align: center; }
.stat .n { display: block; font-family: var(--display); font-size: 1.85rem; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat .l { font-size: .86rem; color: var(--ink-2); line-height: 1.25; display: block; }

.ring-wrap { display: flex; align-items: center; gap: 1rem; }
.ring { flex: 0 0 auto; }
.ring-track { stroke: var(--sunken); }
.ring-fill { stroke: var(--green); transition: stroke-dashoffset .5s ease; }
.ring-num { font-family: var(--display); font-weight: 800; font-size: 19px; fill: var(--ink); }
.ring-label { font-size: .92rem; color: var(--ink-2); }
.step-title { font-family: var(--display); font-weight: 700; font-size: 1.15rem; line-height: 1.25; }

.session-head { display: flex; align-items: center; gap: .7rem; margin-bottom: 1rem; flex-wrap: wrap; }
.session-bar { flex: 1 1 100%; height: .55rem; background: var(--sunken); border-radius: 999px; overflow: hidden; }
.session-bar > div { height: 100%; background: var(--ink); border-radius: 999px; transition: width .2s ease; }
.session-head .sub { flex: 1; font-size: .95rem; font-weight: 700; }

.bar { height: .6rem; background: var(--sunken); border-radius: 999px; overflow: hidden; }
.bar > div { height: 100%; background: var(--ink); border-radius: 999px; }

/* Words by how far they have come, for screens that still draw it as a bar. */
.stage { margin-bottom: .9rem; }
.stage:last-of-type { margin-bottom: 0; }
.stage-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .3rem; }
.stage-title { font-weight: 700; }
.stage-bar { display: flex; gap: 2px; height: .9rem; }
.stage-part { flex: 1 1 0; min-width: 6px; border-radius: 4px; }
.stage-legend { display: flex; flex-wrap: wrap; gap: .1rem .9rem; margin-top: .4rem; font-size: .92rem; color: var(--ink-2); }
.stage-key { display: inline-flex; align-items: center; gap: .35rem; }
.stage-key strong { color: var(--ink); }
.step-1 { background: var(--coral); }
.step-2 { background: var(--amber); }
.step-3 { background: var(--blue); }
.step-4 { background: var(--green); }



/* ---- 14. Words and letters ---- */

.word-big { font-family: var(--display); font-size: 2.3rem; font-weight: 800; line-height: 1.1; overflow-wrap: anywhere; }
@media (min-width: 1200px) { .word-big { font-size: 2.8rem; } }

.syllables { display: flex; gap: .3rem; flex-wrap: wrap; align-items: center; }
.syllable {
    min-height: 2.75rem;
    min-width: 2.75rem;
    padding: .25rem .75rem;
    background: var(--paper);
    color: var(--ink);
    border: 1.5px solid var(--line-strong);
    border-bottom-width: 3px;
    border-radius: 12px;
    font-family: var(--letters);
    font-size: 1.12rem;
    font-weight: 600;
    cursor: pointer;
}
.syllable:hover { background: var(--yellow-soft); border-color: var(--yellow); }
.syllable-sep { color: var(--ink-3); }
.word-pieces { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .3rem .8rem; margin-bottom: .8rem; }

/* The letters I usually get wrong: a swipe of highlighter. */
.trouble { background: linear-gradient(transparent 14%, var(--yellow) 14%, var(--yellow) 90%, transparent 90%); color: var(--on-yellow); border-radius: 3px; padding: 0 .03em; }
.trouble-line { font-family: var(--letters); font-size: 1.55rem; font-weight: 600; letter-spacing: .05em; }

.diff { font-family: var(--letters); font-size: 1.55rem; font-weight: 600; letter-spacing: .05em; word-break: break-all; line-height: 1.4; }
.diff-row { display: flex; align-items: baseline; gap: .7rem; margin-bottom: .2rem; }
.diff-row .who { min-width: 3.4rem; text-align: right; font-family: var(--text); font-size: .86rem; font-weight: 700; letter-spacing: 0; color: var(--ink-3); }
.d-same { color: var(--ink); }
/* Letters that do not belong are struck through, not only coloured. */
.d-extra { color: var(--wrong); text-decoration: line-through; text-decoration-thickness: .12em; background: var(--wrong-bg); border-radius: 4px; }
/* Letters I left out are underlined, so the gap can be seen as well. */
.d-missing { color: var(--right); background: var(--right-bg); border-radius: 4px; box-shadow: inset 0 -.14em 0 var(--green); }

/* Word builder */
.pieces { display: flex; flex-wrap: wrap; gap: .4rem; min-height: 3rem; }
.slots { display: flex; flex-wrap: wrap; gap: .4rem; }
.slot { min-width: 4rem; min-height: 3.2rem; padding: 3px; border: 2px dashed var(--line-strong); border-radius: 14px; display: grid; place-items: stretch; }
.slot-over { border-color: var(--blue); background: var(--blue-soft); }
.slot-right { border-style: solid; border-color: var(--green); background: var(--right-bg); }
.tile {
    display: grid;
    place-items: center;
    min-height: 2.75rem;
    padding: .25rem .8rem;
    background: var(--paper);
    color: var(--ink);
    border: 1.5px solid var(--line-strong);
    border-bottom-width: 3px;
    border-radius: 12px;
    font-family: var(--letters);
    font-size: 1.12rem;
    font-weight: 600;
    cursor: grab;
    touch-action: none;
    user-select: none;
}
.tile-away { opacity: .3; }
.tile-ghost { position: fixed; z-index: 50; transform: translate(-50%, -50%) scale(1.08); box-shadow: var(--lift); pointer-events: none; cursor: grabbing; }

/* ---- 15. Speaking ---- */

.recorder { text-align: center; padding: .5rem 0 .2rem; }
.mic {
    width: 5rem;
    height: 5rem;
    border-radius: 50%;
    border: 0;
    background: var(--primary);
    color: var(--on-primary);
    cursor: pointer;
    display: inline-grid;
    place-items: center;
    box-shadow: 0 0 0 calc(var(--level, 0) * 20px) var(--coral-soft);
    transition: box-shadow .08s linear, transform .06s ease;
}
.mic .icon { width: 2rem; height: 2rem; }
.mic:active { transform: scale(.97); }
.mic:disabled { background: var(--sunken); color: var(--ink-3); cursor: default; }
.mic-on { background: var(--coral); color: var(--on-coral); }
.mic-ico { line-height: 0; display: grid; place-items: center; }
.recorder-label { font-size: .98rem; font-weight: 700; color: var(--ink-2); margin-top: .7rem; }
.take-time { display: flex; align-items: center; gap: .6rem; max-width: 18rem; margin: .5rem auto 0; font-variant-numeric: tabular-nums; }
.take-time .bar { flex: 1; }
.take-time .bar > div { background: var(--coral); }
.mic-options { margin-top: .3rem; }
.mic-options summary { color: var(--link); font-weight: 700; cursor: pointer; min-height: 2.6rem; display: inline-flex; align-items: center; }
.mic-select { width: auto; max-width: 14rem; min-height: 2.75rem; padding: .2rem .5rem; font-size: .92rem; }

.say-sentence { font-family: var(--display); font-size: 1.5rem; line-height: 1.35; font-weight: 600; text-align: center; text-wrap: balance; }
.say-sentence strong { font-weight: 800; background: linear-gradient(transparent 60%, var(--yellow) 60%, var(--yellow) 92%, transparent 92%); color: inherit; }
@media (min-width: 840px) { .say-sentence { font-size: 1.8rem; } }
.say-capture { margin-top: .8rem; padding-top: .8rem; border-top: 1px solid var(--line); }

.clarity-row { display: flex; align-items: center; gap: .9rem; margin-bottom: .9rem; }
.clarity-score { width: 4rem; height: 4rem; flex: 0 0 auto; border-radius: 50%; display: grid; place-items: center; font-family: var(--display); font-size: 1.5rem; font-weight: 800; background: var(--sunken); }
.clarity-score.good { background: var(--right-bg); color: var(--right); }
.clarity-score.close { background: var(--close-bg); color: var(--close); }
.clarity-score.wrong { background: var(--wrong-bg); color: var(--wrong); }

/* What I said, word by word. A right word rests on a straight line, an unsure one on a wave, a wrong one is red too. */
.spoken-words { display: flex; flex-wrap: wrap; gap: .45rem .3rem; font-size: 1.2rem; }
.spoken {
    position: relative;
    min-height: 2.75rem;
    padding: .15rem .5rem .55rem;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}
.spoken:hover { background: var(--sunken); }
.spoken::after { content: ""; position: absolute; left: .45rem; right: .45rem; bottom: .32rem; height: 3px; border-radius: 3px; background: var(--green); }
.spoken.close::after, .spoken.wrong::after, .spoken.missed::after {
    height: .42rem;
    bottom: .18rem;
    border-radius: 0;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 7'%3E%3Cpath d='M0 4.500q3.250-5 6.500 0t6.500 0' fill='none' stroke='%23000' stroke-width='2.400' stroke-linecap='round'/%3E%3C/svg%3E") left center / auto 100% repeat-x;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 7'%3E%3Cpath d='M0 4.500q3.250-5 6.500 0t6.500 0' fill='none' stroke='%23000' stroke-width='2.400' stroke-linecap='round'/%3E%3C/svg%3E") left center / auto 100% repeat-x;
}
.spoken.close::after { background: var(--amber); }
.spoken.wrong::after, .spoken.missed::after { background: var(--coral); }
.spoken.wrong, .spoken.missed { color: var(--wrong); }
.spoken.missed { text-decoration: line-through; }
.spoken.none::after { background: var(--line-strong); }
.spoken.picked { background: var(--sunken); box-shadow: inset 0 0 0 2px var(--ink); }
.spoken .mark { font-size: .7em; margin-left: .15em; }

.word-detail { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: .9rem; }
.sounds { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .8rem; }
.sound { min-width: 3.4rem; min-height: 2.9rem; padding: .3rem .5rem; border: 1.5px solid transparent; border-radius: 12px; text-align: center; background: var(--sunken); color: var(--ink); font: inherit; cursor: pointer; }
.sound.good { background: var(--right-bg); color: var(--right); }
.sound.close { background: var(--close-bg); color: var(--close); }
.sound.wrong { background: var(--wrong-bg); color: var(--wrong); }
.sound.stressed { border-color: currentColor; }
.sound-name { font-weight: 800; font-size: 1rem; }
.sound-example { font-size: .84rem; }

.melody { width: 100%; height: 110px; display: block; }
.melody-axis { stroke: var(--line-strong); stroke-width: 1; }
.melody-ref { stroke: var(--ink-3); stroke-width: 2.5; stroke-dasharray: 6 5; vector-effect: non-scaling-stroke; fill: none; }
.melody-mine { stroke: var(--coral); stroke-width: 2.5; vector-effect: non-scaling-stroke; fill: none; }
.legend { font-size: .9rem; color: var(--ink-2); display: flex; align-items: center; gap: .35rem; margin-top: .3rem; }
.legend .key { width: 18px; height: 3px; display: inline-block; }
.legend .key.ref { background: repeating-linear-gradient(90deg, var(--ink-3) 0 5px, transparent 5px 9px); }
.legend .key.mine { background: var(--coral); margin-left: .6rem; }

/* Talk about a topic */
.topic-title { font-family: var(--display); font-size: 1.5rem; font-weight: 800; line-height: 1.2; text-wrap: balance; }
.topic-prompts { margin: .6rem 0 .9rem; padding-left: 1.2rem; display: grid; gap: .2rem; }
.tip { display: grid; grid-template-columns: 2.75rem minmax(0, 1fr); gap: .8rem; align-items: start; padding: .65rem 0; border-bottom: 1px solid var(--line); }
.tip:first-child { padding-top: 0; }
.tip:last-child { border-bottom: none; padding-bottom: 0; }
.tip-pic { width: 2.75rem; height: 2.75rem; border-radius: 14px; background: var(--yellow-soft); color: var(--ink); display: grid; place-items: center; }
.tip-pic .icon { width: 1.5rem; height: 1.5rem; }
.tip-title { font-weight: 700; }
.fix-better { font-weight: 700; margin: .2rem 0; }

/* ---- 16. Reading and writing ---- */

.passage { font-size: 1.12rem; line-height: 1.75; max-width: var(--prose); }
.gap-text { font-size: 1.12rem; line-height: 2; max-width: var(--prose); }
.gap-input { width: 7.5em; min-height: 2.6rem; padding: .1rem .4rem; border: 1.5px solid var(--line-strong); border-radius: 8px; background: var(--paper); color: var(--ink); font: inherit; }
.draw { width: 100%; height: 220px; background: #fff; border: 1.5px solid var(--line-strong); border-radius: var(--r-control); touch-action: none; display: block; }
.suggestion { border-bottom: 1px solid var(--line); padding: .8rem 0; }
.suggestion:first-child { padding-top: 0; }
.suggestion:last-child { border-bottom: none; padding-bottom: 0; }
.photo-frame { position: relative; line-height: 0; border-radius: var(--r-control); overflow: hidden; }
.photo-frame img { width: 100%; display: block; }
.photo-word { position: absolute; background: color-mix(in srgb, var(--yellow) 35%, transparent); border: 2px solid var(--ink); border-radius: 5px; padding: 0; cursor: pointer; }

/* ---- 17. Folded sections ---- */

.fold { background: var(--paper); border: 1px solid var(--line); border-radius: 16px; margin-bottom: .5rem; }
.fold > summary { display: flex; align-items: center; gap: .6rem; min-height: 3.1rem; padding: .7rem 1.1rem; font-weight: 700; cursor: pointer; list-style: none; }
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after { content: ""; margin-left: auto; width: .55rem; height: .55rem; border-right: 2.5px solid var(--ink-3); border-bottom: 2.5px solid var(--ink-3); transform: rotate(45deg) translate(-2px, -2px); transition: transform .15s ease; flex: 0 0 auto; }
.fold[open] > summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.fold-body { padding: 0 1.1rem 1rem; }
.fold-inner > summary { min-height: 2.75rem; padding: .55rem 0; color: var(--link); font-weight: 700; cursor: pointer; }

/* ---- 18. Settings ---- */

.size-row { display: flex; gap: .5rem; }
.size-btn { flex: 1; min-height: 3.4rem; border: 1.5px solid var(--line-strong); border-radius: var(--r-control); background: var(--paper); color: var(--ink); font-family: var(--display); font-weight: 700; line-height: 1; cursor: pointer; }
.size-btn:hover { background: var(--sunken); }
.size-btn.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* ---- 19. Before .NET has started, and when something breaks ---- */

/* How far the app has loaded, as the squiggle growing across the top of the page. */
.boot-bar {
    position: fixed; top: 3px; left: 0; height: 8px; width: var(--blazor-load-percentage, 0%); background: var(--coral); z-index: 30; transition: width .1s linear;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 8'%3E%3Cpath d='M0 4q3.75-5 7.5 0t7.5 0' fill='none' stroke='%23000' stroke-width='2.6'/%3E%3C/svg%3E") left center / 22px 8px repeat-x;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 8'%3E%3Cpath d='M0 4q3.75-5 7.5 0t7.5 0' fill='none' stroke='%23000' stroke-width='2.6'/%3E%3C/svg%3E") left center / 22px 8px repeat-x;
}
.skeleton { position: relative; overflow: hidden; height: 9rem; background: var(--sunken); border-color: transparent; }
.skeleton::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 25%, color-mix(in srgb, var(--paper) 60%, transparent) 50%, transparent 75%); animation: shimmer 1.5s ease-in-out infinite; }
.skeleton.short { height: 5rem; }
.first-note { text-align: center; color: var(--ink-2); padding: 0 1rem 1rem; }

/* Waiting, in a line of text: the squiggle writes itself and rubs itself out. */
span.spinner {
    display: inline-block; width: 1.9em; height: .62em; vertical-align: .02em; background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 11'%3E%3Cpath d='M2 6q3.75-6 7.5 0t7.5 0 7.5 0 7.5 0' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 11'%3E%3Cpath d='M2 6q3.75-6 7.5 0t7.5 0 7.5 0 7.5 0' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    animation: write-clip 1.3s ease-in-out infinite;
}

/* Only for a fault outside every screen. Above the bottom bar, so the bar can still be used. */
#blazor-error-ui {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 1rem;
    right: 1rem;
    bottom: calc(var(--tabbar) + env(safe-area-inset-bottom, 0px) + 1rem);
    padding: .8rem 1rem;
    background: var(--yellow);
    color: var(--on-yellow);
    border-radius: var(--r-control);
    box-shadow: var(--lift);
    font-weight: 600;
}
#blazor-error-ui .reload { font-weight: 800; margin-left: .4rem; color: inherit; text-decoration: underline; }
@media (min-width: 600px) { #blazor-error-ui { left: auto; right: 1.5rem; bottom: 1.5rem; max-width: 26rem; } }

.update-bar {
    position: fixed;
    left: 50%;
    bottom: calc(var(--tabbar) + env(safe-area-inset-bottom, 0px) + 1rem);
    transform: translateX(-50%);
    z-index: 1000;
    border: 0;
    border-radius: 999px;
    min-height: 2.75rem;
    padding: .6rem 1.2rem;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
    background: var(--ink);
    color: var(--paper);
    box-shadow: var(--lift);
}
@media (min-width: 600px) { .update-bar { bottom: 1.5rem; } }

/* On a work computer the app keeps nothing and offers no microphone. */
.work-computer .recorder .mic, .work-computer .recorder .recorder-label { display: none; }
.work-computer .recorder::after { content: "The microphone is off on this computer."; color: var(--ink-2); font-size: .95rem; }

/* ---- 20. The first run ---- */

/* The welcome: a picture and a few words. Stacked on a phone, side by side where there is room. */
.welcome { display: grid; gap: 1.2rem; max-width: 30rem; margin: 0 auto; }
.welcome > * { min-width: 0; }
.welcome-art {
    position: relative;
    min-height: 15rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.3rem;
    padding: 2.6rem 1.2rem 1.6rem;
    background: var(--hero);
    color: var(--on-hero);
    border-radius: var(--r-card);
    /* The markers, in shades that read on ink. */
    --green: #3ecf8e;
    --blue: #93a0ff;
    --amber: #f3a93c;
}
.welcome-art.only-wide { display: none; }
.welcome-art .wordmark { position: absolute; left: 1.2rem; top: 1rem; font-size: 1.35rem; color: inherit; }
.welcome-art .face { width: 6.5rem; height: 6.5rem; }
.scene-words { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; justify-content: center; }
.scene-word { font-family: var(--letters); font-size: 1.45rem; font-weight: 600; text-decoration: underline; text-underline-offset: .3em; text-decoration-thickness: .12em; }
.scene-word.wrong { text-decoration-style: wavy; text-decoration-color: var(--coral); }
.scene-word.right { text-decoration-color: var(--green); }
.scene-arrow { opacity: .6; }
.scene-lines { display: grid; gap: .9rem; }
.scene-lines > div { display: flex; align-items: center; gap: 1rem; font-family: var(--display); font-weight: 700; font-size: 1.1rem; }
.scene-lines .stage-line { width: 7.5rem; height: 1.75rem; }
.scene-row { display: flex; gap: 1rem; }
.scene-big { width: 4.6rem; height: 4.6rem; border-radius: 50%; display: grid; place-items: center; background: var(--on-hero); color: var(--hero); }
.scene-big .icon { width: 2.1rem; height: 2.1rem; }
.scene-big.hear { background: var(--yellow); color: var(--on-yellow); }
.scene-big.say { background: var(--coral); color: var(--on-coral); }
.scene-dots { display: flex; gap: .9rem; }
.scene-dots span { width: 3.6rem; height: 3.6rem; border: 3px dashed color-mix(in srgb, currentColor 55%, transparent); border-radius: 50%; }

.welcome-say { display: grid; gap: .7rem; justify-items: center; text-align: center; }
.welcome-say h1 { font-size: 1.8rem; }
.welcome-say .sub { font-size: 1rem; }
.welcome-say .notice { margin: 0; }
.welcome-say .dots { padding: 0 0 .2rem; }
.welcome-actions { display: grid; gap: .2rem; justify-items: center; width: 100%; margin-top: .4rem; }
.welcome-next { width: 100%; }
.welcome-say .lang-grid { width: 100%; text-align: left; }

.dots { display: flex; justify-content: center; gap: .45rem; padding: .3rem 0 .9rem; }
.dot { width: .6rem; height: .6rem; border-radius: 50%; background: var(--line-strong); }
.dot.on { background: var(--coral); width: 1.4rem; border-radius: 999px; }

@media (min-width: 840px) {
    .welcome { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2.5rem; align-items: center; max-width: 60rem; min-height: calc(100dvh - 8rem); }
    .welcome-art, .welcome-art.only-wide { display: flex; min-height: 26rem; }
    .welcome-art .face { width: 9rem; height: 9rem; }
    .scene-word { font-size: 1.8rem; }
    .scene-lines .stage-line { width: 10rem; height: 2.35rem; }
    .scene-big { width: 5.6rem; height: 5.6rem; }
    .welcome-say { justify-items: start; text-align: left; }
    .welcome-say h1 { font-size: 2.5rem; }
    .welcome-say .dots { justify-content: flex-start; }
    .welcome-actions { display: flex; align-items: center; gap: .6rem; }
    .welcome-next { width: auto; min-width: 11rem; }
}

.lang-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.2rem, 1fr)); gap: .5rem; }
.lang {
    min-height: 4.4rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .1rem;
    padding: .35rem .2rem;
    border: 1.5px solid var(--line-strong);
    border-radius: var(--r-control);
    background: var(--paper);
    color: var(--ink);
    font: inherit;
    cursor: pointer;
}
.lang:hover { background: var(--sunken); }
.lang-own { font-size: 1.1rem; font-weight: 700; }
.lang-name { font-size: .84rem; color: var(--ink-2); }

/* ---- 21. Old tiles still used by a few screens ---- */

.hub { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr)); gap: .7rem; }
.hub a, .hub-item { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card); padding: 1rem; color: inherit; font: inherit; text-align: left; cursor: pointer; display: grid; gap: .35rem; align-content: start; }
.hub a:hover, .hub-item:hover { border-color: var(--line-strong); text-decoration: none; }
.hub .ico { width: 2.75rem; height: 2.75rem; border-radius: 14px; background: var(--blue-soft); display: grid; place-items: center; }
.hub .ico .icon { width: 1.5rem; height: 1.5rem; }
.hub .ttl { font-weight: 700; display: block; line-height: 1.25; }
.hub .meta { font-size: .9rem; color: var(--ink-2); }

/* With a mouse there is no need for thumb-sized chips. */
@media (hover: hover) and (pointer: fine) and (min-width: 840px) {
    .chip { min-height: 2.3rem; }
}

/* ---- 22. Showing one thing on a phone and another where there is room ---- */

.only-wide { display: none; }
@media (min-width: 840px) {
    .only-wide { display: block; }
    .only-narrow { display: none !important; }
}

.more-group { margin-bottom: 1.6rem; }
.more-group .card-head { margin-bottom: .7rem; }
.more-group h2 { margin: 0; }

/* ---- 23. The words screen ---- */

.pane-empty { min-height: 60dvh; align-content: center; background: var(--paper); border: 1px dashed var(--line-strong); border-radius: var(--r-card); }
.word-view .page-head { margin-bottom: 1rem; }

@media (min-width: 840px) {
    /* Both panes stay put and scroll by themselves, so choosing a word never moves the list. */
    .panes > .pane-list { position: sticky; top: 1.5rem; max-height: calc(100dvh - 3rem); overflow-y: auto; scrollbar-width: thin; padding-right: .35rem; }
    .panes .word-view { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-card); padding: 1.4rem; }
    .panes .word-view .fold { background: transparent; }
}

/* ---- 24. A practice session ---- */

/* The card where one thing is asked. */
.practice { padding: 1.25rem 1.15rem 1.15rem; }
.practice > h3 { margin: 1.1rem 0 .45rem; }
.practice > .notice { margin-bottom: .9rem; }
.practice > .notice.after { margin: .8rem 0 0; }
.practice > .notice > div { margin-top: .2rem; }
.practice > .btn-block.btn-lg { margin-top: .85rem; }
.practice > .word-big { margin: .2rem 0 .5rem; }
.practice .diff { background: var(--page); border-radius: var(--r-control); padding: .75rem .9rem; }
.practice .diff .diff-row:last-child { margin-bottom: 0; }

/* Hearing the word is where a spelling card starts: a round button in highlighter. */
.ask { display: grid; justify-items: center; gap: .35rem; padding: .35rem 0 1.15rem; text-align: center; }
.hear-big {
    display: inline-grid;
    justify-items: center;
    gap: .55rem;
    padding: .25rem .75rem;
    border: 0;
    border-radius: var(--r-card);
    background: none;
    color: var(--ink);
    font: inherit;
    font-family: var(--display);
    font-weight: 700;
    font-size: 1.12rem;
    cursor: pointer;
}
.hear-big .disc { width: 5.4rem; height: 5.4rem; border-radius: 50%; background: var(--yellow); color: var(--on-yellow); display: grid; place-items: center; transition: transform .08s ease, background .12s ease; }
.hear-big .disc .icon { width: 2.3rem; height: 2.3rem; }
.hear-big:hover .disc { background: color-mix(in srgb, var(--yellow) 88%, #14162b); }
.hear-big:active .disc { transform: scale(.95); }
.ask-more { display: flex; align-items: center; justify-content: center; gap: .35rem; flex-wrap: wrap; }
.ask-more.ask-left { justify-content: flex-start; margin: -.3rem 0 .6rem -.7rem; }
.ask-failed { color: var(--wrong); font-size: .92rem; font-weight: 600; }

/* The word itself, when it is meant to be seen. */
.shown-word { display: grid; justify-items: center; gap: .65rem; text-align: center; padding: .4rem 0 1rem; }
.shown-word .syllables { justify-content: center; }
.meaning-line { color: var(--ink-2); max-width: 34ch; }
.meaning-line.left { max-width: var(--prose); margin-bottom: .7rem; }
.meaning-line strong { display: block; color: var(--ink); }
.how-line { text-align: center; color: var(--ink-2); font-weight: 600; margin-bottom: .9rem; }
.practice-actions { align-items: stretch; }
.practice-actions .grow { flex: 1; }

.lbl-row { display: flex; align-items: center; justify-content: space-between; gap: .3rem 1rem; flex-wrap: wrap; margin-bottom: .5rem; }
.lbl-row .lbl { margin: 0; }
.quiet-row { display: flex; justify-content: center; flex-wrap: wrap; gap: 0 .5rem; margin-top: .35rem; }
.quiet-row .btn-block { width: auto; }
.next-due { display: flex; align-items: center; justify-content: center; gap: .4rem; color: var(--ink-2); font-size: .95rem; margin-top: .9rem; }
.next-due .icon { width: 1.1rem; height: 1.1rem; }

.picks { display: grid; gap: .45rem; }
.pick { display: block; width: 100%; min-height: 2.9rem; padding: .65rem .95rem; border: 1.5px solid var(--line-strong); border-radius: var(--r-control); background: var(--paper); color: var(--ink); font: inherit; font-weight: 600; text-align: left; cursor: pointer; }
.pick:hover { background: var(--sunken); }

.gap-ask { margin-bottom: .8rem; }
textarea.input.sentence-box { min-height: 6.5rem; }
.my-sentence { margin: .7rem 0; padding: .7rem .9rem; background: var(--page); border-radius: var(--r-control); }
.said-line { margin: .25rem 0 .9rem; font-size: 1.1rem; }
.said-line s { color: var(--wrong); text-decoration-thickness: .1em; }
.better-line { font-weight: 700; font-size: 1.1rem; margin: .2rem 0 .3rem; }

/* What kind of step this is, with its picture. */
.session-title { display: flex; align-items: center; gap: .7rem; margin-bottom: .7rem; }
.session-title h1 { font-size: 1.35rem; }
.session-title .pic { width: 2.4rem; height: 2.4rem; border-radius: 12px; }
.session-title .pic .icon { width: 1.35rem; height: 1.35rem; }

.session-cols { display: grid; gap: .8rem; }
.session-cols > * { min-width: 0; }
.session-side { display: none; order: -1; }
.session-side.open { display: block; }
.session-side .card:last-child { margin-bottom: 0; }
.session-options h3 { margin: .7rem 0 .4rem; }
.session-options .chips { padding-bottom: 0; }
.so-far { display: flex; align-items: center; gap: .85rem; margin-bottom: .9rem; }
.so-far .face { width: 3.4rem; height: 3.4rem; color: var(--ink); flex: 0 0 auto; }

/* One mark a step: a tick, a squiggle, or the ring for the one in front of me. */
.marks { display: flex; flex-wrap: wrap; gap: .2rem; }
.mark { width: 1.15rem; height: 1.15rem; fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.mark.right { stroke: var(--green); }
.mark.missed { stroke: var(--coral); }
.mark.seen { stroke: var(--ink-3); }
.mark.waiting { fill: var(--line-strong); }
.mark.now { fill: var(--yellow); stroke: var(--ink); stroke-width: 2; }
.marks-big .mark { width: 1.6rem; height: 1.6rem; }

/* The end of a session. */
.finish-main { display: grid; justify-items: center; text-align: center; gap: .5rem; padding: 1.5rem 0 1rem; }
.finish-main .face { width: 6.5rem; height: 6.5rem; color: var(--ink); }
.finish-main h1 { font-size: 2rem; margin-top: .4rem; }
.finish-line { margin: 0; color: var(--ink-2); font-size: 1.1rem; }
.finish-main .marks { justify-content: center; max-width: 24rem; margin: .5rem 0; }
.finish-actions { justify-content: center; margin-top: .8rem; }
.finish-actions .btn-primary { min-width: 9rem; }
.finish-words { display: flex; flex-wrap: wrap; gap: .3rem 1.1rem; margin: .2rem 0 .5rem; }
.word-mark { font-family: var(--letters); font-size: 1.08rem; font-weight: 600; text-decoration: underline; text-underline-offset: .28em; text-decoration-thickness: .12em; line-height: 1.9; }
.word-mark.is-right { text-decoration-color: var(--green); }
.word-mark.is-missed { text-decoration-style: wavy; text-decoration-color: var(--coral); }

@media (min-width: 840px) {
    .session { max-width: 55rem; margin: 0 auto; }
    .session-head { flex-wrap: nowrap; margin-bottom: 1.4rem; }
    .session-head .session-bar { flex: 1 1 auto; }
    .session-head .sub { flex: 0 0 auto; }
    .session-cols { grid-template-columns: minmax(0, 1fr) minmax(14rem, 17.5rem); gap: 1.5rem; align-items: start; }
    .session-side, .session-side.open { display: block; order: 0; position: sticky; top: 1.5rem; }
    .practice { padding: 1.6rem 1.75rem 1.5rem; }

    .finish { max-width: 55rem; margin: 1.5rem auto 0; align-items: center; }
    .finish-main { justify-items: start; text-align: left; }
    .finish-main .marks, .finish-actions { justify-content: flex-start; }
}

/* ---- 25. Saving a word ---- */

.capture-main { display: grid; gap: .8rem; align-content: start; }
.capture-main > * { min-width: 0; }
.capture-main > .notice, .capture-main > .card { margin-bottom: 0; }
.capture-card .input-answer { min-height: 4.4rem; }
.capture-links { gap: 0 .6rem; }
.capture-links .link { font-size: .9rem; }
.capture-save { margin-top: .85rem; }
.field-gap { margin-top: .75rem; }
.notice-more { margin-top: .2rem; }
.did-you-mean { margin-top: 1rem; }
.did-you-mean .sub { margin-top: .5rem; }
.btn.letters { font-family: var(--letters); font-weight: 600; letter-spacing: .03em; }
.quiet-row.start { justify-content: flex-start; margin-left: -.7rem; }
.capture-other { margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.capture-other .capture-ways { margin-top: .45rem; }
.capture-other .say-capture { border-top: 0; padding-top: 0; }
/* Saying the word is one of three ways in, so the microphone is small here and sits beside its label. */
.say-capture .recorder { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem .9rem; text-align: left; padding: 0; }
.say-capture .mic { width: 3.4rem; height: 3.4rem; flex: 0 0 auto; }
.say-capture .mic .icon { width: 1.5rem; height: 1.5rem; }
.say-capture .recorder-label { margin-top: 0; }
.capture-side h2 { margin-top: 0; }
.capture-side .pane-empty { min-height: 0; padding: 1.6rem 1rem; }
.device-line { margin-top: 1rem; color: var(--ink-2); font-size: .92rem; }
.device-line .btn { margin-top: .4rem; }
.word-row .meta .split { font-size: inherit; }

@media (max-width: 839.98px) { .capture-side { margin-top: .6rem; } }
@media (min-width: 840px) { .capture-side { position: sticky; top: 1.5rem; } .capture-card { padding: 1.5rem 1.6rem; } }

/* The "C" hint goes when the shortcut is switched off. */
:root[data-no-shortcut] .side-save kbd { display: none; }

/* Beside the list, the word's main button keeps a button's size. */
@media (min-width: 840px) { .panes .word-view .btn-block.btn-lg { max-width: 22rem; } }

/* ---- 26. When the text is set larger ---- */

/* A hint in a spelling box is only a hint: it may be smaller than what is typed. */
.input-answer::placeholder { font-size: .78em; letter-spacing: .02em; }

/* A long word keeps to one line; its tag and line drop below when there is no room beside it. */
.word-row { flex-wrap: wrap; row-gap: .25rem; }
.word-row .grow { flex: 1 1 8.5rem; }

@media (min-width: 840px) {
    html[data-size="large"] .panes, html[data-size="largest"] .panes { grid-template-columns: minmax(13rem, 17rem) minmax(0, 1fr); }
    html[data-size="largest"] .diff { font-size: 1.3rem; }
}

/* ---- 27. Movement ----
   Things move the way a pen does. A screen arrives, a line writes itself, a mistake is struck
   through, a tick is drawn, a word grows. Nothing moves for its own sake, nothing loops except
   while the app is waiting, and with "reduce motion" switched on everything simply appears. */

:root {
    --ease-out: cubic-bezier(.2, .8, .2, 1);
    --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
    --t-fast: .14s;
    --t: .26s;
    --t-slow: .5s;
}

@keyframes blink {
    0%, 45%, 49%, 100% { transform: scaleY(1); }
    47% { transform: scaleY(.08); }
}
@keyframes blink-soft {
    0%, 46%, 50%, 100% { transform: scaleY(1); }
    48% { transform: scaleY(.35); }
}
@keyframes write {
    0% { stroke-dashoffset: 100; }
    45%, 55% { stroke-dashoffset: 0; }
    100% { stroke-dashoffset: -100; }
}
@keyframes write-clip {
    0% { clip-path: inset(0 100% 0 0); }
    45%, 55% { clip-path: inset(0 0 0 0); }
    100% { clip-path: inset(0 0 0 100%); }
}
@keyframes draw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@keyframes look {
    0%, 100% { transform: translateX(-2.2px); }
    50% { transform: translateX(2.2px); }
}
@keyframes shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: none; } }
@keyframes from-right { from { opacity: 0; transform: translateX(32px); } to { opacity: 1; transform: none; } }
@keyframes from-left { from { opacity: 0; transform: translateX(-32px); } to { opacity: 1; transform: none; } }
@keyframes squiggle-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes grow-up { from { opacity: 0; transform: scale(.15); } to { opacity: 1; transform: none; } }
@keyframes sway {
    0%, 100% { transform: rotate(0deg); }
    30% { transform: rotate(-6deg); }
    70% { transform: rotate(5deg); }
}
@keyframes bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-4px); }
}
@keyframes shake {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-6px); }
    40% { transform: translateX(5px); }
    60% { transform: translateX(-3px); }
    80% { transform: translateX(2px); }
}
@keyframes strike { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes seed-drop {
    0% { opacity: 0; transform: translateY(-26px) scale(.8); }
    60% { opacity: 1; transform: translateY(2px) scale(1.05, .9); }
    100% { opacity: 1; transform: none; }
}

/* A new screen arrives from below, or from the side when I move along the bottom bar. The first
   screen of all does not move: it takes the place of the picture drawn before .NET started. */
.screen { animation: rise var(--t) var(--ease-out) backwards; }
.screen[data-dir="forward"] { animation-name: from-right; }
.screen[data-dir="back"] { animation-name: from-left; }
.screen[data-dir="none"] { animation: none; }

/* While a finger drags the screen sideways towards the next tab. */
main.dragging { transition: none; }
main.settling { transition: transform var(--t) var(--ease-out), opacity var(--t) var(--ease-out); }

/* What a screen is waiting for arrives a moment after the screen does. */
.page > .notice, .page > .empty, .stack > .notice { animation: rise var(--t) var(--ease-out) backwards; }
.count { animation: pop var(--t) var(--ease-spring) backwards; }

/* Things that can be pressed answer the finger. */
.btn-primary:not(:disabled):hover, .btn-coral:not(:disabled):hover { box-shadow: var(--shadow); }
.btn.is-busy { pointer-events: none; opacity: .8; }
.chip { transition: background var(--t-fast) ease, border-color var(--t-fast) ease, color var(--t-fast) ease, transform var(--t-fast) var(--ease-out); }
.chip:active { transform: scale(.95); }
a.row .chev, button.row .chev { transition: transform var(--t-fast) var(--ease-out); }
a.row:hover .chev, button.row:hover .chev { transform: translateX(3px); }
a.row, button.row { transition: background var(--t-fast) ease; }
a.card.card-link { transition: border-color var(--t-fast) ease, transform var(--t) var(--ease-out), box-shadow var(--t) ease; }
a.card.card-link:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
a.card.card-link:active { transform: none; }
.session-bar > div { transition: width .45s var(--ease-out); }
.dot { transition: width var(--t) var(--ease-out), background var(--t) ease; }

/* The bar under the thumb: the icon I land on lifts, and its squiggle writes itself. */
.tabbar a .icon, .side-nav a .icon { transition: transform var(--t) var(--ease-spring); }
.tabbar a.active .icon { transform: translateY(-1px) scale(1.1); }
.tabbar a:active .icon { transform: scale(.9); }
.tabbar a.active::after, .side-nav a.active::after { animation: squiggle-in .4s var(--ease-out) backwards; }
.save-dot, .side-save { transition: transform var(--t) var(--ease-spring), filter var(--t-fast) ease; }
.tabbar a.save:active .save-dot, .side-save:active { transform: scale(.9); }
.side-save .icon, .save-dot .icon { transition: transform var(--t) var(--ease-spring); }
.side-save:hover .icon, .tabbar a.save:hover .save-dot .icon { transform: rotate(90deg); }

/* The face is alive: it blinks, and its mouth arrives with a small bounce when the mood changes. */
.face .eye { transform-box: fill-box; transform-origin: center; animation: blink 5.6s infinite; }
.face.rest .eye { animation: none; }
.face .mouth { transform-box: fill-box; transform-origin: center; animation: pop var(--t) var(--ease-spring) backwards; }
.face[class*="say-"] .mouth { stroke: var(--blue); }
.hero .hero-face { animation: bob 4.5s ease-in-out infinite; }

/* Waiting for a whole screen: the face watches its own mouth write itself. */
.empty.loading { padding: 3rem 1rem; }
.loader-face { width: 5.5rem; height: 5.5rem; color: var(--ink); }
.loader-face .mouth { stroke-dasharray: 100; animation: write 1.5s ease-in-out infinite; }
.loader-face .eye { animation: look 1.5s ease-in-out infinite; }

/* The very first visit downloads the whole app, so it gets the name, large, and a line of hope. */
.splash {
    position: fixed;
    inset: 0;
    z-index: 25;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 1.1rem;
    padding: 1.5rem;
    background: var(--page);
    text-align: center;
}
.splash[hidden] { display: none; }
.splash .wordmark { font-size: clamp(3.2rem, 16vw, 5.5rem); }
.splash .wm-mouth path { stroke-dasharray: 100; animation: write 1.8s ease-in-out infinite; }

/* Every later start: the name in the frame writes its own mouth until the app is ready. */
.wordmark.loading .wm-mouth path { stroke-dasharray: 100; animation: write 1.6s ease-in-out infinite; }
.splash-line { margin: 0; color: var(--ink-2); font-size: 1rem; }
.splash-steps { display: flex; gap: .45rem; align-items: center; font-family: var(--display); font-weight: 700; font-size: 1.05rem; color: var(--ink-3); }
.splash-steps b { color: var(--ink); font-weight: 800; }
.splash-pct::after { content: var(--blazor-load-percentage-text, ""); font-variant-numeric: tabular-nums; }

/* On a phone the name sits above the first screen, because the bar at the bottom has no room for it. */
.brand-line { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin: -.1rem 0 .55rem; }
.brand-line .wordmark { font-size: 1.5rem; }
@media (min-width: 600px) { .brand-line { display: none; } }

/* ---- 28. Words that grow ----
   Every word is drawn as something growing: a seed when I mistook it, a shoot once I retook it, a
   bud while it is taking root, a flower with the app's face once it took root. The colour of each
   stage is the same one the stage bar uses, and a yellow line under a plant means it is due. */

.sprout { display: block; flex: 0 0 auto; width: 2rem; height: 2.5rem; color: var(--ink); overflow: visible; }
.sprout path, .sprout circle, .sprout ellipse { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.sprout .soil { stroke: var(--line-strong); }
.sprout .seed { fill: var(--coral); stroke: var(--coral); }
.sprout .wob { stroke: var(--coral); stroke-width: 1.8; }
.sprout.s2 .leaf { fill: color-mix(in srgb, var(--amber) 55%, var(--paper)); }
.sprout.s3 .leaf, .sprout.s4 .leaf { fill: var(--paper); }
.sprout .bud { fill: var(--blue-soft); stroke: var(--blue); }
.sprout .head { fill: var(--green-soft); stroke: var(--green); }
.sprout .dot { fill: currentColor; stroke: none; }
.sprout .grow { transform-box: fill-box; transform-origin: 50% 100%; animation: grow-up var(--t-slow) var(--ease-spring) backwards; animation-delay: calc(min(var(--i, 0), 16) * 45ms); }
.sprout.planted .grow { animation-name: seed-drop; animation-duration: .7s; }

.garden { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .1rem; margin: .1rem -.3rem .5rem; }
.plant { display: grid; justify-items: center; align-content: end; min-width: 2.75rem; min-height: 3rem; padding: .25rem .3rem .1rem; border-radius: 12px; color: inherit; text-decoration: none; transition: background var(--t-fast) ease; }
.plant:hover { background: var(--sunken); text-decoration: none; }
.plant:hover .sprout .grow, .plant:focus-visible .sprout .grow { animation: sway .9s ease-in-out; }
.plant.due .sprout .soil { stroke: var(--yellow); stroke-width: 5; }
.plant.on { background: var(--sunken); box-shadow: inset 0 0 0 2px var(--ink); }
.plant-word { max-width: 5.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .8rem; font-weight: 600; color: var(--ink-2); line-height: 1.3; }
.garden.with-words { gap: .5rem .2rem; }
.garden-line { display: flex; align-items: center; gap: .5rem; margin: 0 0 .6rem; font-size: .92rem; color: var(--ink-2); }
.garden-line i { flex: 0 0 auto; width: 1.4rem; height: .3rem; border-radius: 3px; background: var(--yellow); }
.stage-row .sprout { width: 1.5rem; height: 1.9rem; }
.stage-key .sprout { width: 1.15rem; height: 1.45rem; }

/* The three steps of one word, said in the app's own words: mistook, retook, took. */
.took-steps { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; margin: 0; padding: 0; list-style: none; font-family: var(--display); font-weight: 700; font-size: .95rem; }
.took-steps li { display: inline-flex; align-items: center; gap: .35rem; color: var(--ink-3); }
.took-steps li + li::before { content: "›"; color: var(--ink-3); font-weight: 400; }
.took-steps span { padding: .2rem .7rem; border-radius: 999px; border: 1.5px solid var(--line-strong); }
.took-steps .done span { color: var(--ink); border-color: var(--ink); }
.took-steps .now span { color: var(--on-yellow); background: var(--yellow); border-color: var(--yellow); animation: pop var(--t) var(--ease-spring) backwards; }
.took-steps .now.s1 span { color: var(--on-coral); background: var(--coral); border-color: var(--coral); }
.took-steps .now.s4 span { color: var(--paper); background: var(--right); border-color: var(--right); }

/* ---- 29. The pen's own marks, for any screen to use ----
   A tick that draws itself, a line struck through a wrong answer, and a small shake of the head. */

.draws path, .draws circle { stroke-dasharray: 100; animation: draw var(--t-slow) var(--ease-out) backwards; }
/* The strike is a line of ink laid along the text itself, so it follows words that wrap onto a second line. */
.struck { background: linear-gradient(var(--coral), var(--coral)) no-repeat 0 58% / 100% max(.13em, 2px); animation: strike-along var(--t-slow) var(--ease-out) backwards; }
@keyframes strike-along { from { background-size: 0 max(.13em, 2px); } }
.shakes { animation: shake .4s ease-in-out backwards; }
.pops { animation: pop var(--t) var(--ease-spring) backwards; }
.rises { animation: rise var(--t) var(--ease-out) backwards; }

/* An arrival fills "backwards": it holds its first picture while it waits its turn and lets go once
   it has arrived, so the thing that arrived can still move under a finger. */

/* With "reduce motion" on, nothing loops and nothing travels: every animation jumps to its end. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ---- 30. The name in the frame ---- */

/* On a laptop the name carries the face, so the face beside it steps aside. */
@media (min-width: 1200px) {
    .brand { padding: .25rem .55rem .85rem; }
    .brand .face { display: none; }
    .brand .wordmark { font-size: 1.95rem; }
}

/* On a phone a sideways drag belongs to the bar at the bottom, and up and down to the page. */
@media (max-width: 599px) { main { touch-action: pan-y pinch-zoom; } }

/* The three words of the name's own story light up one after another while the app downloads. */
.splash-steps span { color: var(--ink); animation: step-on 3.3s infinite; }
.splash-steps span:nth-child(2) { animation-delay: -2.2s; }
.splash-steps span:nth-child(3) { animation-delay: -1.1s; }
@keyframes step-on {
    0%, 30% { color: var(--ink); }
    36%, 100% { color: var(--ink-3); }
}

/* On the dark panel of the welcome, plants are drawn in the panel's own ink. */
.welcome-art .sprout { color: inherit; width: 1.8rem; height: 2.25rem; }
.welcome-art .sprout .soil { stroke: color-mix(in srgb, currentColor 40%, transparent); }
.welcome-art .sprout .leaf { fill: none; }
.welcome-art .sprout .head { fill: color-mix(in srgb, var(--green) 30%, transparent); }
.welcome-art .sprout .bud { fill: color-mix(in srgb, var(--blue) 30%, transparent); }

/* The face can look at what matters: add look-left, look-right or look-down beside the mood. */
.face.look-left .eye { translate: -2.6px 0; }
.face.look-right .eye { translate: 2.6px 0; }
.face.look-down .eye { translate: 0 2.4px; }
.face .eye { transition: translate var(--t) var(--ease-out); }

/* ---- 31. Small pen strokes on Today ---- */

/* A mistake I saved is struck through by the pen, once, when the card arrives. */
.fix s { position: relative; text-decoration: none; }
.fix s::after { content: ""; position: absolute; left: -2%; right: -2%; top: 55%; height: .1em; min-height: 2px; border-radius: 2px; background: currentColor; transform-origin: 0 50%; animation: strike var(--t-slow) var(--ease-out) .35s backwards; }

/* The week's ring fills with one sweep. */
.ring-fill { animation: ring-sweep .9s var(--ease-out) backwards; }
@keyframes ring-sweep { from { stroke-dashoffset: var(--around, 195); } }

/* Before the first word: bare soil, waiting. */
.garden.bare { margin-bottom: .2rem; }
.garden.bare .plant { min-width: 2.4rem; }
.garden.bare .plant:hover { background: none; }
.garden.bare .sprout { color: var(--ink-3); }

/* ---- 32. Movement the practice, speaking and progress screens share ----
   Defined once, here, because a keyframe name is the same name in every stylesheet. */

@property --count { syntax: "<integer>"; initial-value: 0; inherits: false; }
@keyframes count-up { from { --count: 0; } }
@keyframes from-right-again { from { opacity: 0; transform: translateX(32px); } to { opacity: 1; transform: none; } }

/* A number that counts up once: <span class="counts" style="--to:83"></span>, with the real number
   written beside it for a screen reader. It ends on the number, and with "reduce motion" starts there. */
.counts { --count: var(--to, 0); counter-reset: count var(--count); animation: count-up .9s var(--ease-out) backwards; }
.counts::after { content: counter(count); content: counter(count) / ""; }

/* The three steps never break a line on their arrow: the arrow stays with the step before it. */
.took-steps li + li::before { content: none; }
.took-steps li:not(:last-child)::after { content: "A"; color: var(--ink-3); font-weight: 400; }
