/* near black navy with teal glows behind it, solid blue for what matters, mauve and mint only for right and wrong, laid out like a streaming app */
:root {
    --bg: #04070c;
    --surface: #0a121b;
    --surface-2: #101b27;
    --border: #1a2a3a;
    --text: #edf5fa;
    --text-2: #8d9db0;
    --accent: #08699a;
    --accent-hover: #0977ad;
    --accent-text: #4fb0e0;
    --accent-soft: rgba(20, 140, 200, 0.14);
    --on-accent: #ffffff;
    /* filled buttons and bubbles, deep enough at every stop for white text */
    /* flat fills in the accent, with no glow under them */
    --accent-fill: var(--accent);
    --accent-fill-hover: var(--accent-hover);
    --glow: transparent;
    --mauve: #a783a6;
    /* mauve words, a deeper shade in light mode so they stay readable on pale backgrounds */
    --mauve-text: #a783a6;
    --mint: #98dea3;
    --mint-text: #98dea3;
    --record: var(--accent);
    --shadow: rgba(0, 0, 0, 0.5);
    --glass: rgba(10, 18, 27, 0.78);
    /* the floating tabs and message box, lighter than the page so they stand out from it */
    --dock-bg: rgba(27, 42, 58, 0.9);
    --dock-line: rgba(160, 215, 255, 0.18);
    --dock-line-focus: rgba(160, 215, 255, 0.36);
    --dock-active: rgba(160, 215, 255, 0.16);
    --code-bg: #070d14;
    /* a hairline that gives cards an edge, and the lift cards get in light mode */
    --line: rgba(140, 200, 255, 0.09);
    --line-strong: rgba(160, 215, 255, 0.22);
    --card-shadow: 0 0 0 transparent;
    --scroll-thumb: rgba(200, 225, 245, 0.16);
    --scroll-thumb-hover: rgba(200, 225, 245, 0.3);
    /* cards, answer boxes and section boxes are all faint and see through, with a barely there edge */
    --panel-bg: rgba(16, 28, 40, 0.18);
    --panel-line: rgba(140, 200, 255, 0.06);
    --card-bg: var(--panel-bg);
    /* the top of a card, one flat step lighter than the card */
    --art-bg: rgba(22, 38, 54, 0.28);
    /* the page is one flat colour */
    --bg-glow: none;

    --font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-mono: ui-monospace, "Cascadia Code", Consolas, monospace;

    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    /* a quick arrival with a touch of spring, for menus, boxes and toasts that open */
    --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.1);
    --dur: 0.3s;
    /* a serif italic for the big headings, inter for everything else */
    --font-display: 'Newsreader', Georgia, "Times New Roman", serif;
    /* floating boxes lift on a few soft shadows instead of one heavy one */
    --float-shadow: 0 0 0 1px rgba(160, 215, 255, 0.07), 0 24px 54px rgba(0, 0, 0, 0.42), 0 10px 20px rgba(0, 0, 0, 0.26), 0 2px 4px rgba(0, 0, 0, 0.2);
    --gutter: 2rem;
    --pill: 999px;
    /* the chat column, three quarters of the screen on wide screens and never under 760px */
    --chat-w: max(760px, 75vw);
    --card: 12px;
}

[data-theme="light"] {
    --bg: #f3f7fa;
    --surface: #ffffff;
    --surface-2: #e8f0f5;
    --border: #d6e2ea;
    --text: #0c1a26;
    --text-2: #5a6b7b;
    --accent-text: #085c85;
    --accent-soft: rgba(8, 105, 154, 0.08);
    --glow: transparent;
    --mint-text: #2f8a4a;
    --mauve-text: #85527f;
    --record: var(--accent);
    --shadow: rgba(12, 26, 38, 0.16);
    --float-shadow: 0 0 0 1px rgba(12, 26, 38, 0.05), 0 26px 54px rgba(12, 26, 38, 0.06), 0 16px 32px rgba(12, 26, 38, 0.05), 0 10px 16px rgba(12, 26, 38, 0.04), 0 5px 8px rgba(12, 26, 38, 0.03), 0 2px 4px rgba(12, 26, 38, 0.03);
    --glass: rgba(255, 255, 255, 0.86);
    --dock-bg: rgba(226, 235, 242, 0.94);
    --dock-line: rgba(12, 26, 38, 0.14);
    --dock-line-focus: rgba(12, 26, 38, 0.3);
    --dock-active: #ffffff;
    --code-bg: #f6f9fb;
    --line: rgba(12, 26, 38, 0.08);
    --line-strong: rgba(12, 26, 38, 0.16);
    /* a soft shadow so the faint cards still lift off the pale page */
    --card-shadow: 0 1px 2px rgba(12, 26, 38, 0.05), 0 4px 16px rgba(12, 26, 38, 0.07);
    --scroll-thumb: rgba(12, 26, 38, 0.18);
    --scroll-thumb-hover: rgba(12, 26, 38, 0.32);
    --panel-bg: rgba(255, 255, 255, 0.28);
    --panel-line: rgba(12, 26, 38, 0.06);
    --card-bg: rgba(255, 255, 255, 0.45);
    --art-bg: rgba(226, 236, 243, 0.55);
    --bg-glow: none;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 93.75%;
}

html,
body {
    height: 100%;
}

body {
    font-family: var(--font-family);
    background-color: var(--bg);
    background-image: var(--bg-glow);
    background-attachment: fixed;
    color: var(--text);
    line-height: 1.6;
    /* inter set a hair tighter, the way benji's site sets it */
    letter-spacing: -0.006em;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    transition: background-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

button,
select,
textarea {
    font: inherit;
    color: inherit;
}

button {
    cursor: pointer;
    background: none;
    border: none;
}

svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

/* scrollbars are a thin rounded thumb on a clear track with no arrows, so they sit inside whatever is scrolling */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-track,
::-webkit-scrollbar-corner {
    background: transparent;
}

::-webkit-scrollbar-button {
    display: none;
}

::-webkit-scrollbar-thumb {
    border: 3px solid transparent;
    border-radius: var(--pill);
    background: var(--scroll-thumb) padding-box;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--scroll-thumb-hover) padding-box;
}

/* in rounded boxes the bar stops short of the corners so it never pokes out past the curve */
.detail-list::-webkit-scrollbar-track,
.sheet::-webkit-scrollbar-track,
.picker-menu::-webkit-scrollbar-track,
.face::-webkit-scrollbar-track {
    margin-block: 22px;
}

/* firefox has no webkit scrollbar styles, and chrome drops them once these are set, so only firefox gets these */
@supports (-moz-appearance: none) {
    * {
        scrollbar-width: thin;
        scrollbar-color: var(--scroll-thumb) transparent;
    }
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

:focus-visible {
    outline: 2px solid var(--accent-text);
    outline-offset: 2px;
}

/* every button is an oval */
.btn {
    display: inline-flex;
    text-decoration: none;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.65rem 1.4rem;
    border-radius: var(--pill);
    font-size: 0.92rem;
    font-weight: 500;
    transition: background-color 0.2s, box-shadow 0.3s var(--ease-out), transform var(--dur) var(--ease-out);
}

/* a flat blue fill, a shade lighter on hover */
.btn-accent {
    background: var(--accent-fill);
    color: var(--on-accent);
    box-shadow: 0 4px 14px var(--glow);
}

.btn-accent:hover {
    background: var(--accent-fill-hover);
    box-shadow: 0 6px 20px var(--glow);
}

/* disabled buttons go quiet grey instead of a washed out accent */
.btn-accent:disabled {
    background: var(--surface-2);
    color: var(--text-2);
    box-shadow: none;
    cursor: default;
}

/* glass with a thin bright edge, like the outlined buttons in the reference */
.btn-soft {
    background: var(--glass);
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--line-strong);
}

.btn-soft:hover {
    background: var(--surface-2);
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.btn-ghost {
    color: var(--text-2);
}

.btn-ghost:hover {
    background: var(--surface-2);
    color: var(--text);
}

.btn-small {
    padding: 0.45rem 1rem;
    font-size: 0.85rem;
}

.btn-small svg {
    width: 17px;
    height: 17px;
}

.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--pill);
    color: var(--text-2);
    transition: background-color 0.2s, color 0.2s;
}

.icon-btn:hover {
    background: var(--surface-2);
    color: var(--text);
}

/* layout, the window never scrolls, only the thread inside it does */
.main {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

/* the tabs, message box and disclaimer float over the page like a streaming app's bar,
   with the page fading out underneath so the pills stay easy to read */
.dock-wrap {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    padding-top: 2.5rem;
    padding-bottom: env(safe-area-inset-bottom);
    background: linear-gradient(to top, var(--bg) 15%, color-mix(in srgb, var(--bg) 75%, transparent) 50%, transparent);
    pointer-events: none;
}

/* only the pills and text take clicks, the fade lets them through to the page */
.dock-wrap .tabs,
.dock-wrap .composer,
.dock-wrap .disclaimer {
    pointer-events: auto;
}

/* three columns so the page title sits in the middle, the sides grow evenly and never overlap it */
.nav {
    display: grid;
    grid-template-columns: minmax(max-content, 1fr) minmax(0, auto) minmax(max-content, 1fr);
    align-items: center;
    gap: 0.9rem;
    padding: 0.7rem var(--gutter) 0.5rem;
    padding-top: max(0.7rem, env(safe-area-inset-top));
}

.nav-left {
    display: flex;
    align-items: center;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 1.55rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.035em;
    color: #ffffff;
    text-decoration: none;
}

/* white would vanish on the light page, so it follows the text colour there */
[data-theme="light"] .brand {
    color: var(--text);
}

/* the logo is two masks so the R follows the text colour and the diamond stays mauve */
/* the model picker in the message box, a small pill that opens a list upwards.
   the list hangs from the message box, not the pill, so its right edge lines up with the box
   the way the + menu lines up on the left */
.model-tools {
    flex-shrink: 0;
}

.model-tools[hidden] {
    display: none;
}

.model-pick {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    height: 36px;
    padding: 0 0.7rem;
    border: none;
    border-radius: var(--pill);
    background: transparent;
    font: inherit;
    font-size: 0.85rem;
    line-height: 36px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s;
}

.model-pick:hover,
.model-pick[aria-expanded="true"] {
    background: color-mix(in srgb, var(--surface-2) 70%, transparent);
}

.model-pick-name {
    font-weight: 500;
    color: var(--text);
}

.model-pick-word {
    color: var(--text-2);
}

@media (max-width: 480px) {
    .model-pick-word {
        display: none;
    }
}

/* wide enough that each description sits on one line, and never wider than the screen */
.input-menu.model-menu {
    left: auto;
    right: -1px;
    width: max-content;
    min-width: 16rem;
    max-width: min(24rem, calc(100vw - 24px));
}

.model-option {
    justify-content: space-between;
    gap: 1rem;
}

/* the answer language sits under the models, and opens its own scrolling list in the same menu */
.menu-line {
    height: 1px;
    margin: 0.25rem 0.6rem;
    background: var(--border);
}

.lang-now {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--text-2);
}

.lang-now svg {
    width: 14px;
    height: 14px;
}

.lang-back {
    justify-content: flex-start;
}

.lang-back svg {
    width: 16px;
    height: 16px;
}

.lang-options {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: min(52vh, 24rem);
    overflow-y: auto;
}

.model-option > span {
    min-width: 0;
}

.model-option small {
    white-space: nowrap;
}

@media (max-width: 480px) {
    .model-option small {
        white-space: normal;
    }
}

.model-option svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--accent-text);
}

/* the model that wrote an answer, small beside rahah's name */
.tier-tag {
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: var(--pill);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: 0.7rem;
    font-weight: 500;
}

/* the logo exactly as designed, a dark circle with three rising chevrons, the same in every theme */
.logo {
    display: inline-grid;
    place-items: center;
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
}

.logo-img {
    display: block;
    width: 100%;
    height: 100%;
}

.brand .logo-img {
    width: 1.35em;
    height: 1.35em;
    margin-right: 0.45rem;
}

.back-btn {
    display: none;
    margin-left: -0.5rem;
}

.nav-title {
    min-width: 0;
    text-align: center;
    font-size: 1.12rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chat-title {
    display: none;
}

body:not(.is-page) .brand,
body:not(.is-page) .page-title {
    display: none;
}

body:not(.is-page) .back-btn {
    display: inline-grid;
}

body:not(.is-page) .chat-title {
    display: inline;
    font-size: 1.05rem;
    font-weight: 500;
    letter-spacing: 0;
}

.nav-right {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.35rem;
}

/* subject picker, a pill button with a rounded menu that opens just below it */
.picker {
    position: relative;
}

.picker-btn {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    min-width: 11rem;
    max-width: 100%;
    padding: 0.4rem 0.8rem 0.4rem 1rem;
    border-radius: var(--pill);
    background: var(--glass);
    box-shadow: inset 0 0 0 1px var(--line-strong);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    transition: background-color 0.2s, box-shadow 0.2s;
}

.picker-btn:hover,
.picker-btn[aria-expanded="true"] {
    background: var(--surface-2);
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.picker-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.picker-btn svg {
    width: 14px;
    height: 14px;
    color: var(--text-2);
    transition: transform 0.25s var(--ease-out);
}

.picker-btn[aria-expanded="true"] svg {
    transform: rotate(180deg);
}

.picker-menu {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 60;
    display: grid;
    grid-template-columns: repeat(2, minmax(10.5rem, 1fr));
    gap: 0.35rem 0.5rem;
    width: max-content;
    max-width: calc(100vw - 24px);
    max-height: min(70vh, 26rem);
    overflow-y: auto;
    /* the menu only ever scrolls up and down, so no sideways scrollbar shows along its bottom */
    overflow-x: hidden;
    padding: 0.6rem;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--surface);
    box-shadow: var(--float-shadow);
    animation: picker-in 0.22s var(--ease-spring);
}

.picker-menu[hidden],
.field[hidden] {
    display: none;
}

.picker-menu.narrow {
    grid-template-columns: minmax(0, 1fr);
}

.picker-menu.up {
    top: auto;
    bottom: calc(100% + 0.5rem);
    animation-name: picker-in-up;
}

@keyframes picker-in {
    from {
        opacity: 0;
        transform: translateY(-4px) scale(0.97);
    }
}

@keyframes picker-in-up {
    from {
        opacity: 0;
        transform: translateY(4px) scale(0.97);
    }
}

.picker-heading {
    padding: 0.4rem 0.8rem 0.3rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-2);
}

button.picker-heading {
    display: block;
    width: 100%;
    border-radius: var(--pill);
    text-align: left;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

button.picker-heading:hover,
button.picker-heading:focus-visible {
    background: var(--surface-2);
    color: var(--text);
    outline: none;
}

/* the student's own subjects carry a small remove button beside them */
.picker-row {
    display: flex;
    align-items: center;
    gap: 0.15rem;
}

.picker-row .picker-option {
    flex: 1;
    min-width: 0;
}

.picker-remove {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: var(--pill);
    color: var(--text-2);
    transition: background-color 0.15s, color 0.15s;
}

.picker-remove svg {
    width: 14px;
    height: 14px;
}

.picker-remove:hover,
.picker-remove:focus-visible {
    background: var(--surface-2);
    color: var(--text);
}

/* the box at the bottom of every subject menu for typing a new one, pinned there when the menu scrolls */
.picker-add {
    grid-column: 1 / -1;
    position: sticky;
    bottom: 0;
    z-index: 1;
    box-shadow: 0 0 0 0.6rem var(--surface);
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.2rem;
    padding: 0.25rem 0.25rem 0.25rem 0.9rem;
    border-radius: var(--pill);
    background: var(--surface-2);
}

.picker-add:focus-within {
    box-shadow: inset 0 0 0 1px var(--accent-text), 0 0 0 0.6rem var(--surface);
}

.picker-add-input {
    flex: 1;
    min-width: 0;
    padding: 0.35rem 0;
    border: none;
    outline: none;
    background: transparent;
    font: inherit;
    font-size: 0.88rem;
    color: var(--text);
}

.picker-add-input::placeholder {
    color: var(--text-2);
}

.picker-add-btn {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: var(--pill);
    background: var(--accent-fill);
    color: var(--on-accent);
}

.picker-add-btn svg {
    width: 16px;
    height: 16px;
}

.picker-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    width: 100%;
    padding: 0.5rem 0.8rem;
    border-radius: var(--pill);
    font-size: 0.88rem;
    text-align: left;
    white-space: nowrap;
    color: var(--text);
    transition: background-color 0.15s;
}

.picker-option:hover,
.picker-option:focus-visible {
    background: var(--surface-2);
    outline: none;
}

.picker-option[aria-selected="true"] {
    background: var(--accent-soft);
    color: var(--accent-text);
    font-weight: 500;
}

.picker-option svg {
    width: 16px;
    height: 16px;
}

.icon-sun,
[data-theme="light"] .icon-moon {
    display: none;
}

[data-theme="light"] .icon-sun {
    display: block;
}

/* thread, the one scrolling area for both home and chat
   it holds its own positioned pieces, like the hidden copy katex puts beside every formula,
   which would otherwise stretch the whole page and let it scroll past the disclaimer */
.thread {
    position: relative;
    flex: 1;
    overflow-y: auto;
    padding: 1rem 1.5rem;
    scroll-behavior: smooth;
}

.is-page .thread,
.is-study .thread {
    padding: 0 0 1rem;
}

/* empty room at the end of the page as tall as the floating bar, so the last card or message can scroll above it */
.thread::after {
    content: "";
    display: block;
    height: var(--dock-h, 8rem);
}

/* a deck or quiz doesn't use the subject picker, and the message box fades away with the other pages below */
.is-study .mode-picker {
    display: none;
}

.thread > .message {
    max-width: var(--chat-w);
    margin-left: auto;
    margin-right: auto;
}

/* home */
.welcome {
    animation: fade 0.5s var(--ease-out);
}

.greeting {
    padding: 0.75rem var(--gutter) 1.25rem;
}

.greeting p {
    font-size: 0.95rem;
    color: var(--text-2);
}

.greeting h2 {
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

.row {
    position: relative;
    margin-bottom: 1.4rem;
}

/* study, exam and code are small grey labels with room above, the rows under them are named plainly */
.category {
    margin-top: 2.75rem;
}

.category-title {
    padding: 0 var(--gutter);
    margin-bottom: 0.6rem;
    font-family: inherit;
    font-style: normal;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-2);
}

.category .row-title {
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--text);
}

.row-title {
    padding: 0 var(--gutter);
    font-size: 0.95rem;
    font-weight: 500;
    letter-spacing: -0.005em;
}

.row-track {
    display: flex;
    gap: 0.75rem;
    /* the scrolling row clips anything outside it, so it gets room for the full hover shadow above and below,
       pulled back with negative margins so the spacing stays the same */
    padding: 1.6rem var(--gutter) 3.75rem;
    margin: -0.9rem 0 -2.75rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding: 0 var(--gutter);
    overscroll-behavior-x: contain;
    scroll-behavior: smooth;
    scrollbar-width: none;
}

.row-track::-webkit-scrollbar {
    display: none;
}

.row-arrow {
    position: absolute;
    top: calc(50% + 0.9rem);
    z-index: 3;
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border-radius: var(--pill);
    color: var(--text);
    background: var(--glass);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 6px 20px var(--shadow);
    opacity: 0;
    transform: translateY(-50%);
    transition: opacity 0.2s;
}

.row-arrow.prev {
    left: 0.75rem;
}

.row-arrow.next {
    right: 0.75rem;
}

.row-arrow {
    pointer-events: none;
}

@media (hover: hover) {
    .row.can-prev:hover .row-arrow.prev,
    .row.can-next:hover .row-arrow.next,
    .row.can-prev .row-arrow.prev:focus-visible,
    .row.can-next .row-arrow.next:focus-visible {
        opacity: 1;
        pointer-events: auto;
    }
}

/* cards are flat with a hairline edge, and the accent marks what matters on them:
   the sketch, the label and the play button. hovered, the edge firms up and the card lifts a little */
.poster {
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
}

.tile {
    position: relative;
    flex: 0 0 auto;
    width: clamp(200px, 20vw, 270px);
    aspect-ratio: 16 / 10;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 0.9rem 1rem;
    border-radius: var(--card);
    text-align: left;
    color: var(--text);
    scroll-snap-align: start;
    transition: transform 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out);
}

.tile:hover,
.tile:focus-visible {
    transform: translateY(-2px);
    box-shadow: inset 0 0 0 1px var(--line-strong), 0 12px 28px -14px var(--shadow);
}

.tile strong {
    font-size: 0.95rem;
    font-weight: 500;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.tile-sub {
    margin-top: 0.15rem;
    font-size: 0.76rem;
    color: var(--text-2);
}

/* subject picks, a centred label like a category card */
.tile.subject {
    justify-content: center;
    align-items: center;
    text-align: center;
    aspect-ratio: 2 / 1;
}

/* continue studying cards, a poster with an open button and an info strip */
.chat-card {
    flex: 0 0 auto;
    width: clamp(200px, 19vw, 250px);
    border-radius: var(--card);
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
    overflow: hidden;
    scroll-snap-align: start;
    transition: transform 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out);
}

.chat-card:hover,
.chat-card:focus-within {
    transform: translateY(-2px);
    box-shadow: inset 0 0 0 1px var(--line-strong), 0 12px 28px -14px var(--shadow);
}

.chat-card-info {
    position: relative;
}

/* the top of a chat, deck or reminder card sits one flat step lighter, so the card reads as picture and caption */
.chat-card-art.poster,
.reminder-art.poster {
    background: var(--art-bg);
    box-shadow: none;
}

.chat-card-art {
    position: relative;
    display: block;
    aspect-ratio: 16 / 10;
    color: var(--text);
}

/* centred by position rather than grid, since safari doesn't stretch a grid to a box's shape */
.chat-card-art > .play {
    position: absolute;
    inset: 0;
    margin: auto;
}

/* the one solid accent thing on a card, the button that opens it */
.play {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--pill);
    background: var(--accent-fill);
    color: var(--on-accent);
    transition: background-color 0.2s, transform var(--dur) var(--ease-out);
}

.play.outline svg {
    fill: none;
    margin-left: 0;
}

.play svg {
    width: 16px;
    height: 16px;
    margin-left: 2px;
    fill: currentColor;
}

.chat-card-art:hover .play {
    background: var(--accent-fill-hover);
}

.chat-card-info {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.6rem 0.4rem 0.65rem 1rem;
}

.chat-card-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.chat-card-text strong {
    font-size: 0.88rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chat-card-text span {
    font-size: 0.75rem;
    color: var(--text-2);
}

/* the subject line stays on one line, and when it's tight the subject shortens so the time always shows */
.card-meta {
    display: flex;
    min-width: 0;
    white-space: nowrap;
}

.card-meta .meta-what {
    overflow: hidden;
    text-overflow: ellipsis;
}

.card-meta .meta-when {
    flex-shrink: 0;
}

.chat-card .icon-btn {
    width: 34px;
    height: 34px;
}

.chat-card .icon-btn svg {
    width: 17px;
    height: 17px;
}

/* chats and for you pages, cards in a grid grouped under headings */
.list-page {
    padding: 0.5rem var(--gutter) 1rem;
    animation: fade 0.5s var(--ease-out);
}

.page-tools {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.search {
    flex: 1;
    max-width: 360px;
    min-width: 0;
    padding: 0.55rem 1.1rem;
    border: none;
    border-radius: var(--pill);
    background: var(--surface);
    font-size: 0.88rem;
    color: var(--text);
    outline: none;
    transition: background-color 0.2s, box-shadow 0.2s;
}

.search[hidden] {
    display: none;
}

.search:focus {
    background: var(--surface-2);
    box-shadow: 0 0 0 2px var(--accent-soft);
}

.page-tools > .btn:last-child,
.page-tools > .new-chat {
    margin-left: auto;
}

/* on the chats and tests page the flashcards and new test buttons sit beside new chat on the right */
#chats .page-tools > [data-tool="flashcards"] {
    margin-left: auto;
}

#chats .page-tools > [data-tool="quiz"] + .new-chat {
    margin-left: 0;
}

/* the new test card stretches to the height of the test cards beside it */
#chats .card-grid .new-test {
    aspect-ratio: auto;
    min-height: 160px;
}

/* what's on today, under the greeting */
.today-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-top: 0.8rem;
}

.today-strip[hidden],
.today-strip:empty {
    display: none;
}

.today-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.9rem;
    border-radius: var(--pill);
    background: var(--glass);
    box-shadow: inset 0 0 0 1px var(--line-strong);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text);
    transition: box-shadow 0.2s;
}

.today-chip:hover,
.today-chip:focus-visible {
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.today-chip svg {
    width: 16px;
    height: 16px;
    color: var(--accent-text);
}

/* what rahah searched for, a small line above the answer */
.searches {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin: 0 0 0.5rem;
    font-size: 0.8rem;
    color: var(--text-2);
}

.searches svg {
    width: 15px;
    height: 15px;
    margin-top: 0.15rem;
    color: var(--accent-text);
}

.searches q {
    color: var(--text);
}

.source-link {
    display: inline-block;
    margin: 0.35rem 0 0.2rem;
    font-size: 0.82rem;
    color: var(--accent-text);
}

/* thumbs up and down at the end of an answer's actions */
.rate-answer {
    display: inline-flex;
    margin-left: auto;
}

.rate-answer .icon-btn {
    width: 34px;
    height: 34px;
}

.rate-answer svg {
    width: 17px;
    height: 17px;
}

.rate-answer [aria-pressed="true"] {
    color: var(--accent-text);
    background: var(--accent-soft);
}

.unhelpful-list a {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    color: inherit;
    text-decoration: none;
}

.unhelpful-list span {
    font-size: 0.8rem;
    color: var(--text-2);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* a row of small actions under each answer, try again on the latest one */
.answer-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.25rem;
    margin-top: 0.6rem;
    margin-left: -0.6rem;
}

.answer-actions .btn svg,
.notice-retry .btn svg {
    width: 16px;
    height: 16px;
}

.notice-retry {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.75rem;
}

/* what rahah has cost, three windows side by side */
.usage-card {
    margin-top: 1rem;
}

.usage-cols {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.6rem;
}

.usage-col {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.75rem 0.9rem;
    border-radius: 10px;
    background: var(--surface-2);
}

.usage-col span,
.usage-col small {
    font-size: 0.75rem;
    color: var(--text-2);
}

.usage-col strong {
    font-size: 1.3rem;
    font-variant-numeric: tabular-nums;
}

.usage-note {
    margin-top: 0.75rem;
    font-size: 0.85rem;
    color: var(--text-2);
}

.usage-kinds {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.6rem;
}

.usage-kinds span {
    padding: 0.25rem 0.7rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.78rem;
    color: var(--text-2);
}

.usage-kinds strong {
    margin-left: 0.25rem;
    color: var(--text);
    font-weight: 500;
}

@media (max-width: 480px) {
    .usage-cols {
        grid-template-columns: 1fr;
    }
}

/* rows on the performance page that open a details box */
.pick-row,
.bar-row[data-subject] {
    cursor: pointer;
}

tr.pick-row:hover td,
tr.pick-row:focus-visible td {
    background: var(--accent-soft);
}

tr.pick-row:focus-visible {
    outline: none;
}

/* the details box, a smaller and squarer sheet than the others */
.detail-sheet {
    width: min(460px, calc(100vw - 24px));
    border-radius: 14px;
}

.detail-body {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.detail-sub {
    margin-top: -0.6rem;
    font-size: 0.88rem;
    color: var(--text-2);
}

.detail-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
    gap: 0.5rem;
}

.detail-stat {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    background: var(--surface-2);
}

.detail-stat span {
    font-size: 0.72rem;
    color: var(--text-2);
}

.detail-stat strong {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 1.05rem;
}

.detail-heading {
    margin-top: 0.25rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-2);
}

.detail-list {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    max-height: 16rem;
    overflow-y: auto;
    list-style: none;
}

.detail-list li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.45rem 0.75rem;
    border-radius: 10px;
    background: var(--surface-2);
    font-size: 0.88rem;
}

.detail-list li > span:first-child {
    flex: 1;
}

.detail-list .num {
    font-variant-numeric: tabular-nums;
    color: var(--text-2);
}

.detail-name {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.detail-list li.pick-row:hover,
.detail-list li.pick-row:focus-visible {
    box-shadow: inset 0 0 0 1px var(--accent-text);
    outline: none;
}

/* a revision plan, one row per day with a tick and its tasks */
.detail-sheet:has(.plan-days) {
    width: min(560px, calc(100vw - 24px));
}

.plan-days {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-height: min(55vh, 30rem);
    overflow-y: auto;
    list-style: none;
}

.plan-day {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.65rem 0.8rem;
    border-radius: 10px;
    background: var(--surface-2);
}

.plan-day.today {
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.plan-day.done .plan-day-body {
    opacity: 0.55;
}

.plan-check {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    margin-top: 0.15rem;
    accent-color: var(--accent);
    cursor: pointer;
}

.plan-day-body {
    flex: 1;
    min-width: 0;
}

.plan-date {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-2);
}

.plan-day.today .plan-date {
    color: var(--accent-text);
}

.plan-day-body strong {
    display: block;
    margin: 0.1rem 0 0.4rem;
    font-size: 0.95rem;
}

.plan-tasks {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.plan-task {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border-radius: var(--pill);
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--line-strong);
    font-size: 0.78rem;
    color: var(--text);
}

button.plan-task:hover,
button.plan-task:focus-visible {
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.plan-task svg {
    width: 14px;
    height: 14px;
}

.plan-task.rest {
    color: var(--text-2);
}

.plan-days::-webkit-scrollbar-track {
    margin-block: 10px;
}

/* search results from inside chats */
.found-list {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 0.4rem 0 0.5rem;
    list-style: none;
}

.found-list a {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.7rem 0.95rem;
    border-radius: 10px;
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
    color: inherit;
    text-decoration: none;
}

.found-list a:hover,
.found-list a:focus-visible {
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.found-snippet {
    font-size: 0.85rem;
    color: var(--text-2);
}

.found-meta {
    font-size: 0.72rem;
    color: var(--text-2);
}

.found-list mark {
    padding: 0 0.1rem;
    border-radius: 3px;
    background: var(--accent-soft);
    color: var(--accent-text);
}

/* diagrams drawn from rahah's mermaid blocks */
.diagram {
    margin: 0.9rem 0;
    padding: 1rem;
    border: 1px solid var(--panel-line);
    border-radius: 12px;
    background: var(--panel-bg);
    overflow-x: auto;
}

.diagram-art {
    display: flex;
    justify-content: center;
}

.diagram-art img {
    max-width: 100%;
    height: auto;
    max-height: 520px;
}

.diagram-wait {
    color: var(--text-2);
    font-size: 0.85rem;
}

.diagram.failed {
    padding: 0;
    border: 0;
    background: none;
}

.diagram.failed .diagram-art {
    display: block;
}

.diagram.waiting {
    padding: 0;
    border: 0;
    background: none;
}

.diagram.waiting .diagram-art {
    display: block;
}

/* the weekly report on performance */
.week-tiles {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.75rem;
}

.week-tile {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--panel-line);
    border-radius: 12px;
    background: var(--card-bg);
    min-width: 0;
}

.week-tile > span:first-child {
    color: var(--text-2);
    font-size: 0.78rem;
}

.week-tile strong {
    font-size: 1.35rem;
    font-weight: 600;
}

.week-tile small {
    color: var(--text-2);
    font-size: 0.75rem;
}

.week-tile small.up {
    color: var(--accent-text);
}

.week-tile small.down {
    color: var(--mauve-text);
}

.week-days {
    display: flex;
    gap: 0.25rem;
    margin-top: 0.15rem;
}

.week-days i {
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    font-style: normal;
    font-size: 0.62rem;
    color: var(--text-2);
    border: 1px solid var(--panel-line);
}

.week-days i.on {
    color: #fff;
    background: var(--accent);
    border-color: transparent;
}

.week-focus {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1rem;
}

.week-focus p {
    margin: 0;
    color: var(--text-2);
    font-size: 0.88rem;
    line-height: 1.5;
}

.week-focus strong {
    color: var(--text);
}

.week-focus .btn {
    flex-shrink: 0;
    white-space: nowrap;
}

@media (max-width: 900px) {
    .week-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .week-tiles > :last-child {
        grid-column: span 2;
    }

    .week-focus {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* a quiet line under the top bar while there's no internet */
.net-status {
    position: fixed;
    top: calc(var(--nav-h, 60px) + 8px + env(safe-area-inset-top));
    left: 50%;
    transform: translateX(-50%);
    z-index: 30;
    width: max-content;
    max-width: calc(100% - 32px);
    margin: 0;
    padding: 0.45rem 1rem;
    border-radius: var(--pill);
    border: 1px solid var(--panel-line);
    background: var(--dock-bg);
    color: var(--text-2);
    font-size: 0.8rem;
    text-align: center;
    backdrop-filter: blur(12px);
}

.net-status[hidden] {
    display: none;
}

/* voice chat, a soft pulse while it's on */
.talk-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent-text);
    animation: talk-pulse 1.4s ease-in-out infinite;
}

@keyframes talk-pulse {
    50% {
        opacity: 0.3;
        transform: scale(0.7);
    }
}

@media (prefers-reduced-motion: reduce) {
    .talk-dot {
        animation: none;
    }
}

/* while rahah works out who's signed in and which page to open, only the background shows,
   so a refresh never flashes home on the way to another page or the sign in screen */
body.booting .main,
body.booting .dock-wrap,
body.booting .auth {
    visibility: hidden;
}

/* the sign in screen, the app stays hidden behind it */
body.signed-out .main,
body.signed-out .dock-wrap,
body.signed-out .toasts {
    display: none !important;
}

.auth {
    min-height: 100dvh;
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.35fr);
}

.auth[hidden] {
    display: none;
}

.auth-side {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 24px calc(48px + env(safe-area-inset-bottom));
}

.auth-card {
    width: min(360px, 100%);
}

.auth-brand {
    margin: 0 0 2rem;
}

.auth-title {
    margin: 0 0 1.5rem;
    font-size: 1.85rem;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    letter-spacing: -0.01em;
}

/* the right half, with the slides on it */
.auth-stage {
    position: sticky;
    top: 0;
    height: 100dvh;
    overflow: hidden;
}

.auth-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.auth-form .field[hidden],
.auth-link[hidden] {
    display: none;
}

/* outlined boxes on the sign in page, like the reference, instead of the filled ones in the app */
.auth .auth-input {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--border);
}

.auth .auth-input:focus {
    box-shadow: inset 0 0 0 1px var(--accent-text), 0 0 0 3px var(--accent-soft);
}

.auth-label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.auth-link {
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.auth-link:hover {
    color: var(--accent-text);
}

/* the delete button reads in mauve, the colour for things going wrong, so it isn't pressed by accident */
.delete-card .delete-go {
    color: var(--mauve-text);
}

/* a test or deck a friend shared, one card in the middle of the page */
.shared-page {
    display: grid;
    place-items: start center;
    padding: 6vh var(--gutter) 2rem;
}

.shared-card {
    position: relative;
    width: min(100%, 460px);
    padding: 1.6rem;
    text-align: left;
}

.shared-card .study-meta {
    margin-bottom: 0.4rem;
    padding-right: 3.5rem;
    text-align: left;
}

.shared-card .sketch {
    top: 1.2rem;
    right: 1.2rem;
}

.shared-title {
    margin: 0.2rem 0 0.35rem;
    font-size: 1.5rem;
    letter-spacing: -0.02em;
}

.shared-card .btn {
    margin-top: 1.1rem;
}

.shared-card .field-hint {
    margin-top: 0.6rem;
}

.share-link {
    width: 100%;
    margin-top: 0.9rem;
    font-size: 0.82rem;
}

.auth-hint.auth-shared-note {
    margin: -0.2rem 0 1.6rem;
    color: var(--accent-text);
}

/* the leaderboard, friends ranked by this week's points */
.is-leaderboard #leaderboard-btn {
    color: var(--accent-text);
}

/* this week's card, the heading, the rows and the points line evenly spaced */
.board-card {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.board-card .perf-head,
.board-card .perf-head p,
.board-grid .perf-head p {
    margin: 0;
}

.board {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.board-row,
.person {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    border-radius: 12px;
    background: var(--surface-2);
}

.board-row.you {
    background: color-mix(in srgb, var(--accent) 16%, var(--surface-2));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-text) 60%, transparent);
}

.board-place {
    width: 1.6rem;
    text-align: center;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-2);
}

/* first, second and third, their place in gold, silver and bronze with a trophy to match */
.board-row {
    --medal: var(--text-2);
}

.board-row.gold {
    --medal: #f2c94c;
}

.board-row.silver {
    --medal: #c3ccd6;
}

.board-row.bronze {
    --medal: #d08a4e;
}

.board-row .board-place {
    color: var(--medal);
}

.board-row.gold .board-place,
.board-row.silver .board-place,
.board-row.bronze .board-place {
    font-size: 1.05rem;
    font-weight: 600;
}

.board-medal {
    margin-right: -0.15rem;
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--medal) 16%, transparent);
}

.board-trophy {
    width: 20px;
    height: 20px;
    fill: color-mix(in srgb, var(--medal) 35%, transparent);
    stroke: var(--medal);
    stroke-width: 1.7;
}

.account-avatar.small {
    width: 32px;
    height: 32px;
    font-size: 0.85rem;
    flex-shrink: 0;
}

.board-who,
.person-who {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.board-who small,
.person-who small {
    font-size: 0.75rem;
    color: var(--text-2);
}

/* the points in a circle, with pts underneath */
.board-points {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--medal) 70%, transparent);
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.board-row:not(.gold):not(.silver):not(.bronze) .board-points {
    box-shadow: inset 0 0 0 2px var(--border);
}

.board-points strong {
    font-size: 1.05rem;
}

.board-points small {
    font-size: 0.62rem;
    letter-spacing: 0.04em;
    color: var(--text-2);
}

.board-rules {
    margin: 0;
}

/* finding friends, the friends list and the standing, three tall cards side by side */
.board-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin-top: 1rem;
    align-items: stretch;
}

.board-grid .perf-card {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    min-height: 22rem;
    margin: 0;
}

.board-grid .perf-head,
.board-grid .people-list {
    margin: 0;
}

.standing-race {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.standing-race strong {
    font-size: 2.2rem;
    font-weight: 600;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}

.standing-race span {
    color: var(--text-2);
}

.standing-bar {
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.standing-bar span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--accent-fill);
}

.standing-bar-note {
    margin: -0.4rem 0 0;
    font-size: 0.78rem;
    color: var(--text-2);
}

.standing-facts {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    margin: auto 0 0;
}

.standing-facts div {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.55rem 0.75rem;
    border-radius: 10px;
    background: var(--surface-2);
    font-size: 0.85rem;
}

.standing-facts dt {
    color: var(--text-2);
}

.standing-facts dd {
    margin: 0;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.standing-facts dd.up {
    color: var(--mint-text);
}

.standing-facts dd.down {
    color: var(--mauve-text);
}

@media (max-width: 1000px) {
    .board-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

.people-list {
    list-style: none;
    margin: 0.6rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.person-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
}

.friend-finder .search {
    flex: none;
    width: 100%;
    max-width: none;
    margin-top: 0.4rem;
}

.leaderboard-page > .perf-card + .perf-card {
    margin-top: 1rem;
}

@media (max-width: 720px) {
    /* the chats and tests search gets its own full row above the buttons */
    .page-tools {
        flex-wrap: wrap;
        justify-content: flex-end;
    }

    .page-tools .search {
        flex-basis: 100%;
        max-width: none;
    }

    .board-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .board-grid .perf-card {
        min-height: 0;
    }

    .board-who small {
        white-space: normal;
    }
}

/* the message box under the top bar on phones, its menus open downwards from there */
.top-composer {
    position: relative;
    z-index: 15;
    padding: 0 var(--gutter) 0.5rem;
}

.top-composer:empty {
    display: none;
}

.composer-up .composer .input-menu {
    top: calc(100% + 10px);
    bottom: auto;
    animation-name: picker-in;
}

/* a student's photo, cut to a circle */
.avatar-face {
    display: block;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--surface-2);
}

.avatar-face.small,
.account-avatar.small {
    width: 32px;
    height: 32px;
}

.avatar-face.tiny,
.account-avatar.tiny {
    width: 34px;
    height: 34px;
    font-size: 0.9rem;
    text-decoration: none;
}

.avatar-face.large,
.account-avatar.large {
    width: 64px;
    height: 64px;
    font-size: 1.5rem;
}

.photo-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.photo-row .field-hint {
    flex-basis: 100%;
    margin: 0;
}

/* the student's picture in the logo's place before rahah's name, on the tab pages like the name itself */
.has-face .nav .brand .logo-img {
    display: none;
}

.me-face {
    display: inline-flex;
    margin-right: 0.6rem;
    text-decoration: none;
    border-radius: 50%;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-text) 35%, transparent);
    transition: box-shadow 0.2s, transform var(--dur) var(--ease-out);
}

.me-face[hidden],
body:not(.is-page) .me-face {
    display: none;
}

.me-face:hover,
.me-face:focus-visible {
    box-shadow: 0 0 0 2px var(--accent-text);
    transform: scale(1.06);
}


/* plans on the account tab: free and the three passes as cards side by side, the month one lit up */
/* pro and max badges: just the word in bold, nothing behind. white in dark mode and black in light,
   each letter with a thin outline in the opposite colour */
.pro-badge {
    display: inline-block;
    margin-left: 0.35rem;
    font-size: 0.8rem;
    font-weight: 600;
    vertical-align: middle;
    --ink: #fff;
    --edge: rgba(0, 0, 0, 0.55);
    color: var(--ink);
    background: none;
    text-shadow: 0.5px 0 var(--edge), -0.5px 0 var(--edge), 0 0.5px var(--edge), 0 -0.5px var(--edge);
}

.plans {
    margin-top: 1.5rem;
}

.plans-title {
    font-size: 1.35rem;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    letter-spacing: -0.01em;
}

.plans-sub {
    margin: 0.25rem 0 1rem;
    font-size: 0.88rem;
    color: var(--text-2);
}

.plans-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.plans-head .plans-sub {
    margin-bottom: 0;
}

/* week, month or term, an oval switch that changes the prices */
.plan-length {
    display: inline-flex;
    padding: 0.25rem;
    border-radius: 999px;
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line);
}

.plan-length button {
    padding: 0.4rem 1rem;
    border: 0;
    border-radius: 999px;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-2);
    background: none;
    cursor: pointer;
}

.plan-length button.on {
    color: var(--on-accent);
    background: var(--accent-fill);
}

.plan-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
}

.plan-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 1.5rem 1.3rem 1.4rem;
    border-radius: var(--card);
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
}

.plan-card.popular {
    box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent-text) 70%, transparent), 0 14px 34px var(--shadow);
}

.plan-flag {
    position: absolute;
    top: 1.1rem;
    right: 1.1rem;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--accent-text);
    background: var(--accent-soft);
}

.plan-icon {
    width: 44px;
    height: 44px;
    fill: none;
    stroke: var(--accent-text);
    stroke-width: 2.6;
}

.plan-name {
    margin-top: 0.9rem;
    font-size: 1.55rem;
    font-weight: 600;
    letter-spacing: -0.02em;
}

.plan-tag {
    margin-top: 0.15rem;
    font-size: 0.88rem;
    color: var(--text-2);
}

.plan-price {
    margin-top: 1.6rem;
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.plan-price small {
    font-size: 0.85rem;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--text-2);
}

.plan-note {
    min-height: 2.6em;
    margin-top: 0.2rem;
    font-size: 0.8rem;
    line-height: 1.35;
    color: var(--text-2);
}

.plan-btn {
    width: 100%;
    margin-top: 1.2rem;
    justify-content: center;
}

.plan-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

.plan-line {
    height: 1px;
    margin: 1.4rem 0 1.1rem;
    background: var(--border);
}

.plan-plus {
    margin-bottom: 0.7rem;
    font-size: 0.82rem;
    font-weight: 600;
}

.plan-features {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.plan-features li {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-size: 0.88rem;
    line-height: 1.4;
}

.plan-tick {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 0.1rem;
    fill: var(--accent-text);
    stroke: none;
}

.plan-tick path {
    fill: none;
    stroke: var(--bg);
    stroke-width: 2.2;
}

.plans-note {
    margin: 0.9rem 0 0;
}

/* on a phone or small tablet the plans are a row to swipe through, so the page stays short */
@media (max-width: 760px) {
    .plan-grid {
        display: flex;
        gap: 0.75rem;
        margin: 0 calc(-1 * var(--gutter));
        padding: 0.25rem var(--gutter) 0.5rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scrollbar-width: none;
    }

    .plan-grid::-webkit-scrollbar {
        display: none;
    }

    .plan-card {
        flex: 0 0 min(82%, 340px);
        scroll-snap-align: center;
    }
}

/* the exam day pass, a slim card under the plans */
.day-pass {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    margin-top: 1rem;
    padding: 0.9rem 1.1rem;
    border-radius: 14px;
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line);
}

.day-pass .plan-icon {
    width: 32px;
    height: 32px;
}

.day-pass > span {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
}

.day-pass small {
    font-size: 0.8rem;
    color: var(--text-2);
}

/* older chats waiting for pro, at the end of the chats list */
.locked-note {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1rem;
    padding: 0.85rem 1rem;
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.88rem;
    text-decoration: none;
}

.locked-note .pro-badge {
    margin: 0;
}

.model-locked {
    opacity: 0.75;
    text-decoration: none;
    color: inherit;
}

/* the picture at the top gets a blue ring on pro */
.me-face.pro {
    box-shadow: 0 0 0 2px var(--accent-text), 0 0 12px color-mix(in srgb, var(--accent-text) 50%, transparent);
}

[data-theme="light"] .pro-badge {
    --ink: #000;
    --edge: rgba(255, 255, 255, 0.6);
}

/* bigger on the leaderboard, at the far right of each row */
.board-tier {
    flex-shrink: 0;
    width: 2.6rem;
    margin-left: -0.15rem;
    text-align: left;
}

.board-tier .pro-badge {
    margin-left: 0;
    font-size: 0.95rem;
}

@media (max-width: 560px) {
    .board-row {
        gap: 0.5rem;
    }

    .board-tier {
        width: 2rem;
        margin-left: 0;
    }

    .board-medal {
        margin-right: 0;
    }

    .board-tier .pro-badge {
        font-size: 0.82rem;
    }
}

/* the leaderboard's title with the friends or everyone switch beside it */
.board-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* max gets the blue to teal ring round the picture */

.me-face.max {
    box-shadow: 0 0 0 2px #3b6cff, 0 0 0 4px color-mix(in srgb, #22c7b8 70%, transparent), 0 0 14px color-mix(in srgb, #22c7b8 50%, transparent);
}

/* the smaller account cards side by side as tall cards, the students card across the whole row */
.account-rest {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin-top: 1rem;
    align-items: stretch;
}

.account-rest > .perf-card,
.account-rest > #account-end > .perf-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    margin: 0 !important;
}

.account-rest > #account-end {
    display: flex;
}

.account-rest > #account-end > .perf-card {
    flex: 1;
}

.account-rest .account-wide {
    grid-column: 1 / -1;
}

/* in these cards the buttons sit straight under the words, the same in every card */
.account-rest .account-actions {
    margin-top: 0;
    padding-top: 1rem;
}

.account-rest .delete-card .delete-go,
.account-rest .delete-card .account-fields {
    align-self: flex-start;
    margin-top: 0.75rem;
}

.account-rest .text-input {
    width: 100%;
}

@media (max-width: 1000px) {
    .account-rest {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .account-rest {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* today's limit: the pass's own bar and how the pace looks */
.pass-allowance {
    margin-top: 0.75rem;
}

.allowance-label {
    font-size: 0.78rem;
    color: var(--text-2);
}

.pace-note {
    margin: 0.85rem 0 0;
    padding: 0.6rem 0.8rem;
    border-radius: 10px;
    font-size: 0.85rem;
    color: var(--text);
    background: var(--surface-2);
}

/* a switch, an oval with a knob that slides across when it's on */
.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin: 1rem 0 0.25rem;
    padding: 0.7rem 0.85rem;
    border-radius: 12px;
    background: var(--surface-2);
}

.switch-row > span {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.switch-row strong {
    font-size: 0.9rem;
}

.switch-row small {
    font-size: 0.75rem;
    color: var(--text-2);
}

.switch {
    position: relative;
    flex-shrink: 0;
    width: 46px;
    height: 26px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: color-mix(in srgb, var(--text-2) 35%, transparent);
    cursor: pointer;
    transition: background 0.25s var(--ease-out);
}

.switch span {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    transition: transform 0.25s var(--ease-out);
}

.switch[aria-checked="true"] {
    background: var(--accent);
}

.switch[aria-checked="true"] span {
    transform: translateX(20px);
}

/* adding the calendar link, one button per calendar app */
.calendar-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.9rem 0;
}

.calendar-note {
    font-size: 0.8rem;
}

.help-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.support-link {
    color: var(--accent-text);
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.auth-hint {
    margin: 0.4rem 0 0;
    color: var(--text-2);
    font-size: 0.8rem;
    line-height: 1.45;
}

/* forgot password, the button that emails a reset link and what happens next */
.auth-send-reset {
    display: flex;
    margin: 0.55rem 0;
}

.auth-reset-sent {
    display: block;
    margin-bottom: 0.45rem;
    color: var(--mint-text);
}

.auth-reset-sent[hidden] {
    display: none;
}

.auth-reset-help {
    display: block;
}

/* choosing a new password from an email link, google and apple aren't needed */
.auth-resetting #auth-providers {
    display: none;
}

.auth-submit {
    margin-top: 0.4rem;
    width: 100%;
    justify-content: center;
}

.auth-providers {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.auth-providers[hidden] {
    display: none;
}

/* google and apple as outlined ovals in rahah's colours, like the reference */
.auth-provider {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.65rem;
    width: 100%;
    min-height: 44px;
    border: none;
    border-radius: var(--pill);
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--border);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    transition: box-shadow 0.2s var(--ease-out), background 0.2s var(--ease-out);
}

.auth-provider[hidden] {
    display: none;
}

.auth-provider:hover,
.auth-provider:focus-within,
.auth-provider:focus-visible {
    outline: none;
    background: color-mix(in srgb, var(--surface-2) 60%, transparent);
    box-shadow: inset 0 0 0 1px var(--text-2);
}

.auth-provider-face {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    pointer-events: none;
}

.auth-provider svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.apple-logo {
    fill: currentColor;
    stroke: none;
}

/* google's own button sits over ours, unseen, and takes the click */
.auth-google-hit {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: inherit;
    opacity: 0.001;
}

.auth-or {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0.5rem 0 0;
    color: var(--text-2);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.auth-or::before,
.auth-or::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--border);
}

/* the terms box on sign up, with a guardian's ok for anyone under 18 */
.auth-agree {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin: 0.25rem 0 0.9rem;
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--text-2);
    cursor: pointer;
}

.auth-agree input {
    flex-shrink: 0;
    width: 17px;
    height: 17px;
    margin: 0.1rem 0 0;
    accent-color: var(--accent);
    cursor: pointer;
}

.auth-agree a {
    color: var(--text);
}

.auth-agree[hidden] {
    display: none;
}

.auth-legal {
    margin: 1rem 0 0;
    text-align: center;
    font-size: 0.78rem;
    color: var(--text-2);
}

.auth-legal a {
    color: var(--text-2);
}

.auth-switch {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    margin: 1.75rem 0 0;
    color: var(--text-2);
    font-size: 0.85rem;
}

/* phones get the form alone */
@media (max-width: 900px) {
    .auth {
        grid-template-columns: minmax(0, 1fr);
    }

    .auth-stage {
        display: none;
    }
}

/* the suggested for you row on home, with its refresh button beside the heading */
/* the recent flashcards row keeps the same room from the suggestions above it as the sections below */
#home-decks:not(:empty) {
    margin-top: 2.75rem;
}

.category-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-right: var(--gutter);
}

/* a waiting or error line under a category title sits in line with the title */
.category > .page-note {
    padding: 0 var(--gutter);
}

.rec-refresh svg {
    width: 15px;
    height: 15px;
}

/* the account tab */
.account-page .perf-card + .perf-card,
.account-page .account-grid + .perf-card,
.account-page #account-rest .perf-card,
.account-page #usage-slot .perf-card {
    margin-top: 1rem;
}

/* profile and password as two tall cards side by side, each with its boxes stacked */
.account-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    align-items: stretch;
}

.account-page .account-grid .perf-card {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.account-fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    margin-top: 1.25rem;
}

/* the buttons sit at the foot of each card with room above them */
.account-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: auto;
    padding-top: 1.5rem;
}

@media (max-width: 900px) {
    .account-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

.account-actions {
    flex-wrap: wrap;
}

.account-actions .btn {
    white-space: nowrap;
}

/* a note under the buttons, on its own line so the buttons keep their shape */
.account-actions .field-hint {
    flex-basis: 100%;
    margin: 0;
}

/* today's allowance in the usage box */
.allowance {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 1rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--panel-line);
    border-radius: 12px;
    background: var(--card-bg);
}

.allowance-head {
    display: flex;
    justify-content: space-between;
    font-size: 0.85rem;
    color: var(--text-2);
}

.allowance-head strong {
    color: var(--text);
}

.allowance-track {
    height: 8px;
    border-radius: var(--pill);
    background: var(--surface-2);
    overflow: hidden;
}

.allowance-bar {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--accent);
}

.allowance-bar.full {
    background: var(--mauve-text);
}

.allowance small {
    color: var(--text-2);
    font-size: 0.75rem;
}

.usage-bar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 8rem;
}

.usage-bar .allowance-track {
    flex: 1;
}

.usage-bar-value {
    min-width: 2.6rem;
    text-align: right;
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

/* the students page */
.admin-table td small {
    display: block;
    color: var(--text-2);
    font-size: 0.75rem;
}

.admin-table tr.is-off td {
    opacity: 0.55;
}

.admin-cap {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--text-2);
}

.admin-cap .text-input {
    width: 6.5rem;
    padding: 0.4rem 0.75rem;
    font-size: 0.85rem;
}

.admin-tag {
    color: var(--text-2);
    font-size: 0.82rem;
}

.admin-actions {
    white-space: nowrap;
    text-align: right;
}

.account-admin {
    margin-top: 0.6rem;
}

/* who's signed in, at the top of settings */
.account-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.account-avatar {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}

.account-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.account-text small {
    color: var(--text-2);
    font-size: 0.78rem;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.account-password {
    margin-top: 0.6rem;
}

.account-password-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-top: 0.5rem;
}

.account-password-form .btn {
    align-self: flex-start;
}

.account-box:empty {
    display: none;
}

.account-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1rem;
}

.account-links:empty {
    display: none;
}

/* the connect buttons are the sign in page's ovals, sized to their words */
.account-links .account-provider {
    width: auto;
    min-width: 230px;
    padding: 0 1.25rem;
}

.account-linked {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--text-2);
    font-size: 0.82rem;
}

.account-linked svg {
    width: 15px;
    height: 15px;
    color: var(--accent-text);
}

/* settings */
.field-hint {
    margin: 0 0 0.5rem;
    color: var(--text-2);
    font-size: 0.82rem;
    line-height: 1.45;
}

/* the notes library on the chats and tests page */
.section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.note-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: grid;
    gap: 0.5rem;
}

.note-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem 0.6rem 0.9rem;
    border: 1px solid var(--panel-line);
    border-radius: 12px;
    background: var(--panel-bg);
}

.note-icon svg {
    width: 20px;
    height: 20px;
    color: var(--accent-text);
}

.note-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.note-text strong {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-weight: 500;
}

.note-text small {
    color: var(--text-2);
    font-size: 0.78rem;
}

.note-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.25rem;
}

.note-actions .icon-btn {
    width: 34px;
    height: 34px;
}

.note-actions .icon-btn svg {
    width: 17px;
    height: 17px;
}

.note-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.5rem;
}

.note-pill svg {
    color: var(--accent-text);
}

.file-pill.failed {
    color: var(--mauve-text);
}

@media (max-width: 720px) {
    .note-row {
        flex-wrap: wrap;
    }

    .note-actions {
        width: 100%;
        justify-content: space-between;
        flex-wrap: nowrap;
        gap: 0;
    }

    .note-actions .btn {
        padding-inline: 0.5rem;
        gap: 0.3rem;
    }
}

/* printing, only the print area shows, black on white */
#print-area {
    display: none;
}

@media print {
    body.printing {
        background: #fff !important;
        color: #000;
    }

    body.printing > *:not(#print-area) {
        display: none !important;
    }

    body.printing #print-area {
        display: block;
        color: #000;
        font: 11pt / 1.5 "Inter", sans-serif;
    }

    #print-area .print-head {
        display: flex;
        justify-content: space-between;
        padding-bottom: 6pt;
        margin-bottom: 12pt;
        border-bottom: 1px solid #000;
        font-size: 13pt;
    }

    #print-area .print-head span,
    #print-area .print-sub,
    #print-area .print-marks {
        font-size: 9pt;
        color: #444;
    }

    #print-area ol {
        padding-left: 24pt;
    }

    #print-area .print-q,
    #print-area .print-cards > li {
        margin-bottom: 14pt;
        break-inside: avoid;
    }

    #print-area .print-options {
        list-style: upper-alpha;
    }

    #print-area .print-lines span {
        display: block;
        height: 20pt;
        border-bottom: 1px solid #999;
    }

    #print-area .print-key {
        break-before: page;
    }

    #print-area .print-back {
        margin-top: 4pt;
        padding-left: 8pt;
        border-left: 2px solid #999;
    }

    #print-area .print-question {
        font-weight: 600;
        margin-bottom: 8pt;
    }

    #print-area a {
        color: #000;
    }

    #print-area .sources details {
        display: block;
    }
}

/* the big headings that split a page into parts, like tests and chats */
.section-title {
    margin: 2.25rem 0 0.7rem;
    font-family: inherit;
    font-style: normal;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-2);
}

/* the new chat drop down, the same rounded box as the + menu but opening down from the button */
.new-chat {
    position: relative;
}

.new-chat-menu {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 300px;
    max-width: calc(100vw - 24px);
    padding: 0.45rem;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--surface);
    box-shadow: var(--float-shadow);
    animation: picker-in 0.22s var(--ease-spring);
}

.new-chat-menu[hidden] {
    display: none;
}

.new-chat-heading {
    margin: 0.45rem 0.9rem 0.15rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-2);
}

.recent-option {
    text-decoration: none;
}

/* long chat titles stop at one line */
.recent-text {
    min-width: 0;
}

.recent-text strong {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.page-note {
    font-size: 0.85rem;
    color: var(--text-2);
}

.page-note.wait {
    margin-top: 10vh;
    text-align: center;
    font-size: 0.95rem;
}

/* reminders, a poster with the countdown and an info strip with what to do */
.tool-buttons {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
}

.page-note.on {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--mint-text);
}

.page-note.on svg {
    width: 16px;
    height: 16px;
}

.card-grid.reminder-grid {
    grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
}

.reminder-actions .btn {
    white-space: nowrap;
}

.reminder-card {
    display: flex;
    flex-direction: column;
    border-radius: var(--card);
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
    overflow: hidden;
    scroll-snap-align: start;
}

.row-track .reminder-card {
    flex: 0 0 auto;
    width: clamp(270px, 22vw, 300px);
}

.reminder-art {
    position: relative;
    height: 128px;
    padding: 0.85rem 0.9rem;
    color: var(--text);
}

.countdown {
    position: absolute;
    left: 1rem;
    bottom: 0.75rem;
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}

.countdown strong {
    font-size: 2.1rem;
    font-weight: 600;
    letter-spacing: -0.03em;
    line-height: 1;
}

.countdown span {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-2);
}

/* today and tomorrow are the only countdowns in the accent, so the colour means it's close */
.reminder-card.soon .countdown strong {
    color: var(--accent-text);
}

.reminder-info {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.7rem 0.6rem 0.55rem 1rem;
    min-width: 0;
}

.reminder-info > strong {
    font-size: 0.95rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.reminder-info > span {
    font-size: 0.78rem;
    color: var(--text-2);
}

.reminder-info > .reminder-next {
    color: var(--text);
}

.reminder-notes {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.reminder-actions {
    display: flex;
    align-items: center;
    gap: 0.1rem;
    margin-top: 0.4rem;
}

.reminder-actions .spacer {
    flex: 1;
}

.reminder-actions .icon-btn {
    width: 34px;
    height: 34px;
}

.reminder-actions .icon-btn svg {
    width: 17px;
    height: 17px;
}

.reminder-card.past {
    opacity: 0.62;
}

/* reminder pop ups, near the top and out of the way of the message box */
/* the reminders tab split in half, reminders on the left and the weekly timetable on the right,
   each in a faint see through box with a hairline edge and no shadow, one under the other when narrow */
.planner {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem;
    align-items: stretch;
}

.planner-col {
    min-width: 0;
    padding: 1.1rem 1.25rem 1.25rem;
    border-radius: var(--card);
    background: var(--panel-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line);
}

/* title on the left, buttons on the right, on one line */
.planner-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem 1rem;
}

.planner-title {
    font-size: clamp(1.3rem, 2.2vw, 1.6rem);
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    letter-spacing: -0.01em;
}

/* one line under the title, with the notifications switch on the right of the reminders one */
.planner-note-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem 1rem;
    margin: 0.4rem 0 0.3rem;
}

.planner-note {
    flex: 1 1 16rem;
    font-size: 0.85rem;
    color: var(--text-2);
}

.planner-note-row .page-note {
    font-size: 0.85rem;
}

.planner-empty {
    max-width: 340px;
    margin: 2.5rem auto 1.5rem;
    text-align: center;
    font-size: 0.9rem;
    color: var(--text-2);
}

.planner-empty strong {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 1rem;
    color: var(--text);
}

.planner .reminder-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.timetable-day {
    margin-top: 1rem;
}

.timetable-day-title {
    margin-bottom: 0.4rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-2);
}

.timetable-day.today .timetable-day-title {
    color: var(--accent-text);
}

.class-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.4rem;
    padding: 0.5rem 0.35rem 0.5rem 0.85rem;
    border-radius: 12px;
    background: var(--surface-2);
}

/* the class happening right now gets a lit edge */
.class-row.now {
    background: color-mix(in srgb, var(--accent) 16%, var(--surface-2));
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.class-time {
    display: flex;
    flex-direction: column;
    min-width: 3rem;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
}

.class-time strong {
    font-size: 0.88rem;
    font-weight: 600;
}

.class-time span {
    font-size: 0.75rem;
    color: var(--text-2);
}

.class-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.class-info strong,
.class-info span {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* a long class name wraps onto a second line rather than being cut off */
.class-info strong {
    font-size: 0.92rem;
    font-weight: 500;
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.class-info span {
    font-size: 0.76rem;
    color: var(--text-2);
}

.class-now {
    flex-shrink: 0;
    padding: 0.15rem 0.6rem;
    border-radius: var(--pill);
    background: var(--accent-fill);
    color: var(--on-accent);
    font-size: 0.7rem;
    font-weight: 600;
}

.class-row .icon-btn {
    width: 34px;
    height: 34px;
}

.class-row .icon-btn svg {
    width: 17px;
    height: 17px;
}

.timetable-free {
    padding: 0.2rem 0.1rem;
    font-size: 0.85rem;
    color: var(--text-2);
}

@media (max-width: 900px) {
    .planner {
        grid-template-columns: 1fr;
        gap: 1.25rem;
    }
}

/* when the buttons drop under the title they line up on the left */
@media (max-width: 720px) {
    .planner-head .tool-buttons {
        justify-content: flex-start;
    }
}

.toasts {
    position: fixed;
    top: 76px;
    left: 50%;
    z-index: 40;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: min(540px, calc(100vw - 24px));
    transform: translateX(-50%);
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.7rem 0.7rem 0.7rem 0.9rem;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface);
    box-shadow: var(--float-shadow);
    pointer-events: auto;
    animation: toast-in 0.3s var(--ease-spring);
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translateY(-6px) scale(0.97);
    }
}

.toast .sketch {
    position: static;
    flex-shrink: 0;
}

.toast-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    font-size: 0.88rem;
}

.toast-text strong {
    font-weight: 500;
}

.toast-text span {
    font-size: 0.8rem;
    color: var(--text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.toast-actions {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    flex-shrink: 0;
}

/* the + button and its menu of files, photo and voice, opening upwards from the message box.
   both menus hang from the whole box, so they open above any chips or files sitting over the text */
.input-tools {
    flex-shrink: 0;
}

.tools-btn svg {
    transition: transform 0.3s var(--ease-out);
}

.tools-btn[aria-expanded="true"] {
    background: var(--surface-2);
    color: var(--text);
}

.tools-btn[aria-expanded="true"] .icon-plus {
    transform: rotate(45deg);
}

.tools-btn .icon-mic,
.tools-btn.listening .icon-plus {
    display: none;
}

/* while listening the + is a mic in the accent colour and the message box glows the same, nothing pulses */
.tools-btn.listening {
    background: var(--record);
    color: #ffffff;
}

.tools-btn.listening .icon-mic {
    display: block;
}

.input-menu {
    position: absolute;
    bottom: calc(100% + 10px);
    left: -1px;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 280px;
    max-width: calc(100vw - 24px);
    padding: 0.45rem;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--surface);
    box-shadow: var(--float-shadow);
    animation: picker-in-up 0.22s var(--ease-spring);
}

.input-menu[hidden],
.input-option[hidden] {
    display: none;
}

.input-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.5rem 0.9rem 0.5rem 0.5rem;
    border-radius: var(--pill);
    text-align: left;
    color: var(--text);
    transition: background-color 0.15s;
}

.input-option:hover,
.input-option:focus-visible {
    background: var(--surface-2);
    outline: none;
}

.opt-icon {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: var(--pill);
    background: var(--accent-soft);
    color: var(--accent-text);
}

.opt-icon svg {
    width: 19px;
    height: 19px;
}

.input-option strong {
    display: block;
    font-size: 0.9rem;
    font-weight: 500;
}

.input-option small {
    display: block;
    font-size: 0.76rem;
    color: var(--text-2);
}

.composer-box.listening {
    box-shadow: 0 0 0 2px var(--record), 0 10px 30px var(--shadow);
}

/* camera sheet, a live preview with the buttons underneath */
.camera-stage {
    position: relative;
    display: grid;
    place-items: center;
    aspect-ratio: 4 / 3;
    border-radius: var(--card);
    background: #0e1014;
    overflow: hidden;
}

.camera-stage video,
.camera-stage img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* the live picture fills the box, which takes the camera's shape, kept short enough to leave room for the buttons */
.camera-stage {
    max-height: 62vh;
}

.camera-stage video {
    object-fit: cover;
}

.camera-stage video[hidden],
.camera-stage img[hidden] {
    display: none;
}

/* the front camera is shown like a mirror, the photo itself isn't flipped */
.camera-stage video.mirror {
    transform: scaleX(-1);
}

.camera-note {
    position: absolute;
    max-width: 80%;
    text-align: center;
    font-size: 0.9rem;
    color: #c9ccd6;
}

.camera-note[hidden] {
    display: none;
}

.camera-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.camera-actions .spacer {
    flex: 1;
}

.camera-actions [hidden] {
    display: none;
}

/* text, date and time boxes in the sheets, pills like everything else */
.text-input {
    width: 100%;
    min-width: 0;
    padding: 0.7rem 1rem;
    border: none;
    border-radius: var(--pill);
    outline: none;
    background: var(--surface-2);
    font: inherit;
    font-size: 0.95rem;
    color: var(--text);
    color-scheme: dark;
}

[data-theme="light"] .text-input {
    color-scheme: light;
}

.text-input::placeholder {
    color: var(--text-2);
}

.text-input:focus {
    box-shadow: 0 0 0 2px var(--accent-soft);
}

.reminder-preview {
    margin-top: -0.4rem;
    font-size: 0.82rem;
    color: var(--accent-text);
}

/* hand drawn sketches on cards, each line draws itself in once when the card first shows */
.filters {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.sketch {
    position: absolute;
    top: 0.75rem;
    right: 0.8rem;
    width: 54px;
    height: 54px;
    color: var(--accent-text);
    stroke-width: 2.3;
    pointer-events: none;
}

.sketch.inline {
    position: static;
    width: 44px;
    height: 44px;
    margin-bottom: 0.3rem;
}

.sketch.small {
    top: 0.9rem;
    right: 0.95rem;
    width: 38px;
    height: 38px;
    color: var(--accent-text);
    opacity: 0.8;
    stroke-width: 2.6;
}

.sketch g > * {
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
    animation: sketch-draw 1.3s var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 70ms + var(--s, 0) * 220ms + 150ms);
}

.sketch .pass {
    opacity: 0.4;
    stroke-width: 1.4;
}

/* the second pass follows a moment behind the first */
.sketch .pass > * {
    animation-duration: 1.6s;
}

.sketch g > :nth-child(2) { --s: 1; }
.sketch g > :nth-child(3) { --s: 2; }
.sketch g > :nth-child(4) { --s: 3; }
.sketch g > :nth-child(n + 5) { --s: 4; }

@keyframes sketch-draw {
    from {
        stroke-dashoffset: 1;
    }
}

/* a card waiting to scroll into view keeps its sketch for then */
.reveal-row:not(.shown) .sketch g > *,
.reveal-grid:not(.shown) .sketch g > *,
.reveal:not(.shown) .sketch g > * {
    animation-play-state: paused;
}

.chat-card-art,
.stat-card {
    position: relative;
}

/* a stat card that opens a box, like average gpa */
.stat-card.pick-card {
    cursor: pointer;
    transition: box-shadow 0.2s var(--ease-out), transform 0.3s var(--ease-out);
}

.stat-card.pick-card:hover,
.stat-card.pick-card:focus-visible {
    outline: none;
    transform: translateY(-2px);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-text) 45%, transparent), var(--card-shadow);
}

.gpa-list .gpa-track {
    flex: 0 1 6rem;
    min-width: 2.5rem;
}

.gpa-list .allowance-track {
    display: block;
}

.gpa-list .gpa-tests {
    color: var(--text-2);
    font-size: 0.8rem;
    min-width: 3.5rem;
}

/* a long subject name wraps onto a second line rather than being cut off */
.gpa-list .detail-name {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* a suggestion card, what to do on top, then the topic and why */
.card-grid .tile {
    width: auto;
}

.tile.rec {
    aspect-ratio: auto;
    min-height: 190px;
    gap: 0.15rem;
}

.rec-chip {
    position: absolute;
    top: 0.85rem;
    left: 0.9rem;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.75rem 0.25rem 0.6rem;
    border-radius: var(--pill);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: 0.72rem;
    font-weight: 500;
}

.rec-chip svg {
    width: 14px;
    height: 14px;
}

.tile.rec .tile-sub {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.4;
}

.rec-subject {
    margin-top: 0.35rem;
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-2);
}

.group-title {
    margin: 1.25rem 0 0.6rem;
    font-family: inherit;
    font-style: normal;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-2);
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.9rem;
    margin-bottom: 1rem;
}

.card-grid .chat-card {
    width: auto;
}

.page-empty {
    max-width: 420px;
    margin: 12vh auto 0;
    text-align: center;
    color: var(--text-2);
}

.page-empty strong {
    display: block;
    margin-bottom: 0.3rem;
    font-size: 1.15rem;
    color: var(--text);
}

.page-empty .btn {
    margin-top: 1.1rem;
}

/* the sheet that sets up a tool, a centred panel on wide screens and a bottom sheet on phones */
.sheet {
    margin: auto;
    width: min(520px, calc(100vw - 24px));
    max-height: calc(100dvh - 24px);
    padding: 0;
    border: none;
    border-radius: 18px;
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--float-shadow);
}

/* boxes ease in when they open and out when they close, the page adds closing for the way out */
.sheet {
    opacity: 0;
    transform: translateY(10px) scale(0.97);
    transition: opacity 0.2s var(--ease-out), transform 0.32s var(--ease-spring), overlay 0.3s allow-discrete, display 0.3s allow-discrete;
}

.sheet[open] {
    opacity: 1;
    transform: none;
}

.sheet[open].closing {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
    transition-duration: 0.16s, 0.16s;
    transition-timing-function: ease-in, ease-in;
}

@starting-style {
    .sheet[open] {
        opacity: 0;
        transform: translateY(10px) scale(0.97);
    }
}

.sheet::backdrop {
    background: rgba(2, 6, 12, 0);
    backdrop-filter: blur(0);
    transition: background-color 0.3s var(--ease-out), backdrop-filter 0.3s var(--ease-out), overlay 0.3s allow-discrete, display 0.3s allow-discrete;
}

.sheet[open]::backdrop {
    background: rgba(2, 6, 12, 0.55);
    backdrop-filter: blur(6px);
}

.sheet[open].closing::backdrop {
    background: rgba(2, 6, 12, 0);
    transition-duration: 0.22s;
}

@starting-style {
    .sheet[open]::backdrop {
        background: rgba(2, 6, 12, 0);
    }
}

.sheet-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.3rem 1.4rem 1.25rem;
}

.sheet-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-right: -0.4rem;
}

.sheet-top h2 {
    font-size: 1.25rem;
    font-weight: 600;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    min-width: 0;
}

.field-label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-2);
}

.field textarea {
    min-height: 88px;
    padding: 0.8rem 1rem;
    border: none;
    border-radius: 12px;
    outline: none;
    resize: vertical;
    background: var(--surface-2);
    font-size: 0.95rem;
    line-height: 1.5;
}

.field textarea::placeholder {
    color: var(--text-2);
}

.field textarea:focus {
    box-shadow: 0 0 0 2px var(--accent-soft);
}

.sheet .picker-btn {
    width: 100%;
    background: var(--surface-2);
}

.sheet .picker-btn:hover,
.sheet .picker-btn[aria-expanded="true"] {
    background: var(--border);
}

.sheet .picker-menu {
    left: 0;
    right: auto;
    background: var(--surface-2);
}

/* the add box covers what scrolls under it in the menu's own colour */
.sheet .picker-add {
    background: var(--surface);
    box-shadow: 0 0 0 0.6rem var(--surface-2);
}

.sheet .picker-add:focus-within {
    box-shadow: inset 0 0 0 1px var(--accent-text), 0 0 0 0.6rem var(--surface-2);
}

.sheet .picker-option:hover,
.sheet .picker-option:focus-visible {
    background: var(--border);
}

/* setup sheet, what to do with the subject picked at the top */
.setup-hint {
    margin-top: 0.2rem;
    font-size: 0.88rem;
    color: var(--text-2);
}

.setup-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
}

.setup-action {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.8rem 1.15rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--text);
    text-align: left;
    transition: background-color 0.2s, color 0.2s;
}

.setup-action svg {
    width: 18px;
    height: 18px;
    color: var(--accent-text);
}

.setup-action:hover,
.setup-action:focus-visible {
    background: var(--accent-soft);
    outline: none;
}

.setup-action.primary {
    background: var(--accent-fill);
    color: var(--on-accent);
}

.setup-action.primary svg {
    color: var(--on-accent);
}

.setup-action.primary:hover,
.setup-action.primary:focus-visible {
    background: var(--accent-fill-hover);
}

@media (max-width: 480px) {
    .setup-actions {
        grid-template-columns: 1fr;
    }
}

.sheet-files {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.sheet-files:empty {
    display: none;
}

.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.field-row:has(> .field[hidden]) {
    grid-template-columns: 1fr;
}

.choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.choice {
    min-width: 44px;
    padding: 0.45rem 0.95rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-2);
    transition: background-color 0.2s, color 0.2s;
}

.choice[aria-pressed="true"] {
    background: var(--accent-fill);
    color: var(--on-accent);
}

.sheet-error {
    padding: 0.65rem 1rem;
    border-radius: 12px;
    background: rgba(167, 131, 166, 0.18);
    font-size: 0.88rem;
}

.sheet-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
}

.sheet-note {
    margin-right: auto;
    font-size: 0.8rem;
    color: var(--text-2);
}

/* decks and quizzes */
.study {
    max-width: 720px;
    margin: 0 auto;
    padding: 0.75rem var(--gutter) 2rem;
    animation: fade 0.4s var(--ease-out);
}

.study-meta {
    margin-bottom: 0.75rem;
    text-align: center;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-2);
}

.flashcard {
    display: block;
    height: clamp(260px, 50vh, 440px);
    border-radius: 16px;
    perspective: 1400px;
    cursor: pointer;
}

.flashcard-inner {
    position: relative;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform 0.6s var(--ease-out);
}

.flashcard.flipped .flashcard-inner {
    transform: rotateY(180deg);
}

.face {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 2.5rem 2rem 2rem;
    border-radius: 16px;
    text-align: center;
    overflow-y: auto;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    box-shadow: var(--float-shadow);
}

.face.front {
    color: var(--text);
}

/* the back is one step lighter than the front, so turning the card over is easy to see */
.face.back {
    background: var(--surface-2);
    transform: rotateY(180deg);
}

.face-label {
    position: absolute;
    top: 1.1rem;
    left: 1.4rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-2);
}

.face-text {
    max-width: 34rem;
    font-size: 1.3rem;
    font-weight: 500;
    line-height: 1.45;
}

.face.back .face-text {
    font-size: 1.1rem;
    font-weight: 500;
}

/* the start of a test and its countdown */
.quiz-start .timer-field {
    align-items: center;
    margin: 1.25rem 0 0.5rem;
}

.quiz-start .choices {
    justify-content: center;
}

.quiz-timer {
    font-variant-numeric: tabular-nums;
    color: var(--accent-text);
}

.quiz-timer.low {
    color: var(--mauve-text);
    font-weight: 600;
}

/* after a card is flipped, say how it went */
.rate-row {
    display: flex;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 1rem;
}

.rate-row[hidden] {
    display: none;
}

.box-name {
    font-weight: 600;
}

.box-1 {
    color: var(--mauve-text);
}

.box-2,
.box-3,
.box-4 {
    color: var(--accent-text);
}

.box-5 {
    color: var(--mint-text);
}

.study-controls {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.25rem;
}

.icon-btn.round {
    width: 48px;
    height: 48px;
    background: var(--surface);
    color: var(--text);
}

.icon-btn.round:hover {
    background: var(--surface-2);
}

.icon-btn:disabled {
    opacity: 0.35;
    cursor: default;
}

.study-extra {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.4rem;
    margin-top: 0.6rem;
}

.study-extra .btn {
    white-space: nowrap;
}

.quiz-progress {
    height: 6px;
    margin-bottom: 1rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    overflow: hidden;
}

.quiz-progress span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--accent);
    transition: width var(--dur) var(--ease-out);
}

.quiz-question {
    font-size: 1.3rem;
    font-weight: 500;
    line-height: 1.45;
}

.quiz-options {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 1.25rem;
}

.option {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    padding: 0.6rem 1.4rem 0.6rem 0.6rem;
    border: 1.5px solid transparent;
    border-radius: var(--pill);
    background: var(--surface);
    text-align: left;
    transition: background-color 0.2s, border-color 0.2s;
}

.option:hover:not(:disabled) {
    background: var(--surface-2);
}

.option:disabled {
    cursor: default;
}

.option-key {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.8rem;
    font-weight: 600;
}

.option.correct {
    border-color: var(--mint);
    background: rgba(152, 222, 163, 0.12);
}

.option.correct .option-key {
    background: var(--mint);
    color: #04070c;
}

.option.wrong {
    border-color: var(--mauve-text);
    background: rgba(167, 131, 166, 0.14);
}

.option.wrong .option-key {
    background: var(--mauve);
    color: #ffffff;
}

.feedback {
    margin-top: 1rem;
    padding: 1rem 1.25rem;
    border-radius: 14px;
    background: var(--surface);
}

.feedback strong {
    display: block;
    margin-bottom: 0.2rem;
    color: var(--mint-text);
}

.feedback.wrong strong {
    color: var(--mauve-text);
}

/* reviewing mistakes after a test, each missed question with the right answer side by side */
.review {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    max-width: 720px;
    margin: 0 auto;
    padding-bottom: 1rem;
}

.review .study-meta {
    text-align: left;
}

.review-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 1rem 1.15rem 1.1rem;
    border-radius: var(--card);
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
}

.review-head {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-2);
}

.review-question {
    font-weight: 500;
}

.review-answers {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.6rem;
    width: 100%;
}

.review-answer {
    padding: 0.6rem 0.8rem;
    border-radius: 10px;
    background: var(--surface-2);
}

.review-answer > span {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.72rem;
    font-weight: 600;
}

.review-answer.wrong > span {
    color: var(--mauve-text);
}

.review-answer.right > span {
    color: var(--mint-text);
}

.review-why {
    font-size: 0.9rem;
    color: var(--text-2);
}

.review-item .btn svg {
    width: 17px;
    height: 17px;
}

/* some of the marks, between right and wrong */
.feedback.partial strong {
    color: var(--accent-text);
}

/* a written answer, a box to type in, a photo of the working and the mic */
.written {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 1rem;
}

.written-answer {
    width: 100%;
    min-height: 8rem;
    padding: 0.9rem 1.1rem;
    border-radius: 14px;
    resize: vertical;
    line-height: 1.5;
}

.written-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.written-tools[hidden] {
    display: none;
}

.written-tools .spacer {
    flex: 1;
}

.written-tools .btn svg {
    width: 17px;
    height: 17px;
}

.written-tools .listening {
    box-shadow: inset 0 0 0 1px var(--accent-text);
    color: var(--accent-text);
}

.written-photo {
    position: relative;
    width: fit-content;
    max-width: 100%;
}

.written-photo img {
    display: block;
    max-width: min(100%, 360px);
    max-height: 260px;
    border-radius: 12px;
    box-shadow: inset 0 0 0 1px var(--line);
}

.written-photo .icon-btn {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 32px;
    height: 32px;
    background: var(--glass);
    color: var(--text);
}

.model-answer {
    margin-top: 0.75rem;
}

.model-answer summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--accent-text);
}

.model-answer .answer {
    margin-top: 0.4rem;
}

.quiz-results {
    padding-top: 8vh;
    text-align: center;
}

.score {
    font-size: 3.5rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--text-2);
}

.score strong {
    color: var(--text);
}

.score-note {
    margin-top: 0.4rem;
    color: var(--text-2);
}

/* the score after a test, in a ring that fills to the share of marks */
.score-ring {
    --ring: var(--accent-text);
    display: grid;
    place-items: center;
    width: 168px;
    height: 168px;
    margin: 0.6rem auto 0.4rem;
    border-radius: 50%;
    background: conic-gradient(var(--ring) calc(var(--pct) * 1%), color-mix(in srgb, var(--text-2) 18%, transparent) 0);
    animation: ring-in 0.8s var(--ease-out) backwards;
}

.score-ring.high {
    --ring: var(--mint-text);
}

.score-ring.low {
    --ring: var(--mauve-text);
}

.score-ring-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 144px;
    height: 144px;
    border-radius: 50%;
    background: var(--bg);
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.score-ring-inner strong {
    font-size: 2.7rem;
    font-weight: 600;
    letter-spacing: -0.03em;
}

.score-ring-sign {
    margin-left: 0.05em;
    font-size: 0.55em;
    font-weight: 600;
    color: var(--ring);
}

.score-ring-inner small {
    margin-top: 0.3rem;
    font-size: 0.85rem;
    color: var(--text-2);
}

@keyframes ring-in {
    from { opacity: 0; transform: scale(0.85); }
    to { opacity: 1; transform: none; }
}

/* the line above each question, previous on the left and the question number in the middle */
.quiz-top {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.quiz-top .study-meta {
    margin: 0;
}

.quiz-prev {
    justify-self: start;
}

.quiz-prev svg,
[data-quiz="forward"] svg {
    width: 16px;
    height: 16px;
}

.past-answer {
    margin-bottom: 0.75rem;
}

/* performance, stat tiles, charts and tables, all in the accent on slate */
.performance {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 0.5rem var(--gutter) 1.5rem;
    animation: fade 0.5s var(--ease-out);
}

.stat-card {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    width: clamp(190px, 17vw, 240px);
    min-height: 132px;
    padding: 1rem 1.15rem;
    border-radius: var(--card);
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
    text-align: left;
    scroll-snap-align: start;
}

.stat-label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-2);
}

.stat-value {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 1.9rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.stat-value.small {
    font-size: 1.2rem;
    letter-spacing: -0.01em;
}

.stat-note {
    font-size: 0.78rem;
    color: var(--text-2);
}

.stat-card .spark {
    margin-top: auto;
    padding-top: 0.4rem;
    overflow: visible;
}

.spark path {
    fill: none;
    stroke: var(--text-2);
    stroke-width: 1.5;
    opacity: 0.7;
}

.spark circle {
    fill: var(--accent);
}

.stat-card.more {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--text-2);
    transition: background-color 0.2s, color 0.2s, transform var(--dur) var(--ease-out);
}

.stat-card.more:hover {
    background: var(--surface-2);
    color: var(--text);
}

.grade-pill {
    display: inline-grid;
    place-items: center;
    min-width: 1.7rem;
    height: 1.7rem;
    padding: 0 0.45rem;
    border-radius: var(--pill);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0;
}

.delta {
    font-weight: 500;
}

.delta.up {
    color: var(--mint-text);
}

.delta.down {
    color: var(--mauve-text);
}

.kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 0.9rem;
}

.kpis .stat-card {
    width: auto;
}

.kpis + .kpis {
    margin-top: 0.9rem;
}

.perf-card {
    position: relative;
    padding: 1.1rem 1.25rem 1.25rem;
    border-radius: 14px;
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
}

.perf-head h3 {
    font-size: 1.05rem;
    font-weight: 600;
}

.perf-head p {
    margin-bottom: 0.75rem;
    font-size: 0.8rem;
    color: var(--text-2);
}

.perf-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

/* line chart */
.chart {
    position: relative;
}

/* charts set their own strokes, so they don't take the icon outline every other svg gets */
.chart svg,
.spark {
    display: block;
    overflow: visible;
    fill: none;
    stroke: none;
}

.chart .grid {
    stroke: var(--border);
    stroke-width: 1;
}

.chart .tick {
    fill: var(--text-2);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.chart .area {
    fill: var(--accent);
    opacity: 0.1;
}

.chart .line {
    fill: none;
    stroke: var(--accent);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.chart .end-dot,
.chart .hover-dot {
    fill: var(--accent);
    stroke: var(--surface);
    stroke-width: 2;
}

.chart .end-label {
    fill: var(--text);
    font-size: 12px;
    font-weight: 500;
}

.chart .crosshair {
    stroke: var(--text-2);
    stroke-width: 1;
    opacity: 0.6;
}

.chart .hit {
    fill: transparent;
    cursor: crosshair;
}

.chart-tip {
    position: absolute;
    z-index: 4;
    display: flex;
    flex-direction: column;
    min-width: 9rem;
    max-width: 16rem;
    padding: 0.55rem 0.8rem;
    border-radius: 10px;
    background: var(--surface-2);
    box-shadow: var(--float-shadow);
    font-size: 0.78rem;
    color: var(--text-2);
    transform: translate(-50%, calc(-100% - 14px));
    pointer-events: none;
}

.chart-tip.floating {
    position: fixed;
    z-index: 40;
    transform: translate(-50%, calc(-100% - 8px));
}

.chart-tip[hidden] {
    display: none;
}

.chart-tip strong {
    font-size: 1rem;
    color: var(--text);
}

/* subject bars, they grow from the left and carry their value at the tip */
.bars {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.bar-row {
    display: grid;
    grid-template-columns: minmax(90px, 10rem) 1fr;
    align-items: center;
    gap: 0.75rem;
    border-radius: 8px;
}

.bar-label {
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bar-track {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.bar {
    flex-shrink: 0;
    width: calc((100% - 5.5rem) * var(--v) / 100);
    height: 14px;
    border-radius: 0 4px 4px 0;
    background: var(--accent);
    transition: filter 0.2s;
}

.bar-value,
.col-value {
    font-size: 0.8rem;
    font-weight: 500;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* grade columns */
.columns {
    display: flex;
    gap: 0.5rem;
}

.col {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    border-radius: 8px;
}

.col-plot {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    width: 100%;
    height: 130px;
    border-bottom: 1px solid var(--border);
}

.col-value {
    margin-bottom: 0.3rem;
}

.col-bar {
    width: 22px;
    border-radius: 4px 4px 0 0;
    background: var(--accent);
    transition: filter 0.2s;
}

.col-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-2);
}

.bar-row:hover .bar,
.bar-row:focus-visible .bar,
.col:hover .col-bar,
.col:focus-visible .col-bar {
    filter: brightness(1.18);
}

.scale-note {
    margin-top: 0.8rem;
    font-size: 0.75rem;
    color: var(--text-2);
}

/* tables */
.perf-details summary {
    display: inline-flex;
    margin-top: 0.75rem;
    padding: 0.4rem 0.95rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    list-style: none;
}

.perf-details summary::-webkit-details-marker {
    display: none;
}

.table-wrap {
    margin-top: 0.5rem;
    overflow-x: auto;
}

.table-wrap table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.table-wrap th {
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
    text-align: left;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-2);
    white-space: nowrap;
}

.table-wrap td {
    padding: 0.55rem 0.6rem;
    border-bottom: 1px solid var(--border);
}

.table-wrap tr:last-child td {
    border-bottom: none;
}

.table-wrap .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.table-wrap .row-action {
    text-align: right;
}

/* chat messages */
.message {
    margin-bottom: 1.25rem;
    animation: rise 0.35s var(--ease-out);
}

.message.user {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.user .bubble {
    max-width: 80%;
    padding: 0.7rem 1.2rem;
    border-radius: 22px;
    background: var(--accent-fill);
    color: var(--on-accent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.user .files {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}

.message.assistant {
    padding: 1rem 1.3rem 1.15rem;
    border-radius: 14px;
    background: var(--card-bg);
    box-shadow: inset 0 0 0 1px var(--panel-line), var(--card-shadow);
}

.file-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    max-width: 260px;
    padding: 0.35rem 0.85rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.8rem;
    font-weight: 500;
}

.file-pill span {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.file-pill svg {
    width: 14px;
    height: 14px;
}

.file-pill.uploading,
.file-pill.failed {
    color: var(--text-2);
}

.file-pill button {
    display: grid;
    place-items: center;
    color: var(--text-2);
}

.file-pill button:hover {
    color: var(--text);
}

.assistant .label {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin-bottom: 0.35rem;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-2);
}

.assistant .label .logo {
    width: 1.5rem;
    height: 1.5rem;
    margin-right: 0.1rem;
}

/* rendered answer */
.answer {
    overflow-wrap: anywhere;
}

.answer > * + * {
    margin-top: 0.85rem;
}

.answer h1,
.answer h2,
.answer h3,
.answer h4 {
    line-height: 1.3;
    letter-spacing: -0.3px;
    margin-top: 1.4rem;
}

.answer h1 { font-size: 1.4rem; }
.answer h2 { font-size: 1.2rem; }
.answer h3 { font-size: 1.05rem; }

.answer ul,
.answer ol {
    padding-left: 1.4rem;
}

.answer li + li {
    margin-top: 0.3rem;
}

.answer a {
    color: var(--accent-text);
    text-underline-offset: 3px;
}

.answer blockquote {
    padding-left: 1rem;
    border-left: 3px solid var(--mauve);
    color: var(--text-2);
}

.answer table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
    display: block;
    overflow-x: auto;
}

.answer th,
.answer td {
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    text-align: left;
}

.answer th {
    background: var(--surface-2);
}

.answer hr {
    border: none;
    border-top: 1px solid var(--border);
}

.answer :not(pre) > code {
    padding: 0.15rem 0.45rem;
    border-radius: 8px;
    background: var(--surface-2);
    font-family: var(--font-mono);
    font-size: 0.86em;
}

.answer pre {
    position: relative;
    border-radius: 12px;
    background: var(--code-bg);
    overflow: hidden;
}

.answer pre code {
    display: block;
    padding: 1rem 1.15rem;
    overflow-x: auto;
    font-family: var(--font-mono);
    font-size: 0.86rem;
    line-height: 1.55;
}

.code-actions {
    position: absolute;
    top: 0.55rem;
    right: 0.55rem;
    display: flex;
    gap: 0.35rem;
    opacity: 0;
    transition: opacity 0.2s;
}

.answer pre:hover .code-actions,
.code-actions:focus-within {
    opacity: 1;
}

@media (hover: none) {
    .code-actions {
        opacity: 1;
    }
}

.code-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.8rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-2);
    transition: background-color 0.2s, color 0.2s;
}

.code-btn:hover {
    color: var(--text);
}

.code-btn svg {
    width: 12px;
    height: 12px;
}

.run-btn {
    background: var(--accent-soft);
    color: var(--accent-text);
}

.run-btn:hover {
    background: var(--accent);
    color: var(--on-accent);
}

/* code runs, a card with the code claude ran and what came out */
.run {
    margin: 1rem 0;
    border: 1px solid var(--border);
    border-radius: var(--card);
    background: var(--surface);
    overflow: hidden;
}

.run-head {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.6rem 0.9rem;
    font-size: 0.85rem;
    font-weight: 500;
}

.run-head svg {
    width: 18px;
    height: 18px;
    color: var(--accent-text);
}

.run-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.run-path {
    font-family: var(--font-mono);
    font-weight: 500;
}

.run-status {
    flex-shrink: 0;
    padding: 0.15rem 0.7rem;
    border-radius: var(--pill);
    font-size: 0.72rem;
    font-weight: 500;
}

.run-status.ok {
    background: color-mix(in srgb, var(--mint) 18%, transparent);
    color: var(--mint-text);
}

.run-status.fail {
    background: color-mix(in srgb, var(--mauve) 22%, transparent);
    color: var(--mauve-text);
}

.run-status.busy {
    background: var(--accent-soft);
    color: var(--accent-text);
}

.answer .run pre {
    margin: 0;
    border-radius: 0;
    border-top: 1px solid var(--border);
}

.answer .run pre code {
    max-height: 22rem;
    overflow: auto;
}

.answer .run-output {
    max-height: 18rem;
    overflow: auto;
    padding: 0.85rem 1.15rem;
    background: var(--surface-2);
    font-family: var(--font-mono);
    font-size: 0.82rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}

.run-output .stderr {
    color: var(--mauve-text);
}

.run-files {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    padding: 0.75rem 0.9rem;
    border-top: 1px solid var(--border);
}

.run-image {
    display: block;
    max-width: 100%;
}

.run-image img {
    display: block;
    max-width: 100%;
    max-height: 26rem;
    border-radius: 10px;
    background: #ffffff;
}

.run-file {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.9rem;
    border-radius: var(--pill);
    background: var(--surface-2);
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
}

.run-file:hover {
    background: var(--accent-soft);
}

.run-file svg {
    width: 15px;
    height: 15px;
}

.katex-display {
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0.25rem 0;
}

/* code colours from the palette */
.hljs-keyword,
.hljs-selector-tag,
.hljs-built_in,
.hljs-title,
.hljs-section {
    font-weight: 500;
}

.hljs-keyword,
.hljs-selector-tag {
    color: var(--accent-text);
}

.hljs-string,
.hljs-attr,
.hljs-template-variable {
    color: var(--mint-text);
}

.hljs-comment,
.hljs-quote,
.hljs-meta {
    color: var(--text-2);
    font-style: italic;
}

.hljs-number,
.hljs-literal {
    color: var(--mauve-text);
}

/* citations */
.cite {
    display: inline-grid;
    place-items: center;
    min-width: 1.3rem;
    height: 1.3rem;
    margin: 0 1px;
    padding: 0 0.35rem;
    border-radius: var(--pill);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: 0.7rem;
    font-weight: 600;
    vertical-align: 0.15em;
    transition: background-color 0.2s, color 0.2s;
}

.cite:hover {
    background: var(--accent);
    color: var(--on-accent);
}

.sources {
    margin-top: 1rem;
    padding-top: 0.85rem;
    border-top: 1px solid var(--border);
}

.sources-title {
    margin-bottom: 0.4rem;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-2);
}

.source {
    border-radius: 10px;
    transition: background-color 0.3s;
}

.source.flash {
    background: var(--accent-soft);
}

.source summary {
    display: flex;
    gap: 0.5rem;
    padding: 0.35rem 0.6rem;
    font-size: 0.85rem;
    cursor: pointer;
    list-style: none;
}

.source summary::-webkit-details-marker {
    display: none;
}

.source .n {
    min-width: 1.25rem;
    font-weight: 600;
    color: var(--accent-text);
}

.source .where {
    color: var(--text-2);
}

.source blockquote {
    margin: 0 0.6rem 0.5rem 2.35rem;
    padding-left: 0.75rem;
    border-left: 2px solid var(--mauve);
    font-size: 0.85rem;
    color: var(--text-2);
    white-space: pre-wrap;
}

/* thinking label, errors and notes */
.thinking {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.2rem 0;
    font-size: 0.92rem;
    color: var(--text-2);
}

.thinking .spark {
    font-size: 1.05rem;
    color: var(--accent-text);
}

.notice {
    margin-top: 0.75rem;
    padding: 0.75rem 1rem;
    border-radius: 12px;
    background: var(--surface-2);
    font-size: 0.9rem;
    color: var(--text-2);
}

/* bottom dock, a floating tab bar beside the message box */
.dock {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 0.6rem;
    width: 100%;
    max-width: 920px;
    margin: 0 auto;
    padding: 0.5rem 1.5rem 0;
}

.tabs {
    display: flex;
    gap: 2px;
    padding: 4px;
    border-radius: var(--pill);
    background: var(--dock-bg);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    box-shadow: inset 0 0 0 1px var(--dock-line), 0 10px 30px var(--shadow);
}

.tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    min-width: 60px;
    padding: 0.25rem 0.8rem 0.2rem;
    border-radius: var(--pill);
    font-size: 0.64rem;
    font-weight: 500;
    color: var(--text-2);
    transition: background-color 0.2s, color 0.2s;
}

.tab:hover {
    color: var(--text);
}

.tab svg {
    width: 18px;
    height: 18px;
}

.tab {
    position: relative;
}

/* how many reminders are due in the next few days */
.tab-badge {
    position: absolute;
    top: 2px;
    right: 10px;
    display: grid;
    place-items: center;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: var(--pill);
    background: var(--accent);
    color: var(--on-accent);
    font-size: 0.65rem;
    font-style: normal;
    font-weight: 600;
}

.tab-badge[hidden] {
    display: none;
}

.is-home .tab[data-tab="home"],
.is-chats .tab[data-tab="chats"],
.is-account .tab[data-tab="account"],
.is-reminders .tab[data-tab="reminders"],
.is-performance .tab[data-tab="performance"] {
    background: var(--dock-active);
    color: var(--text);
}

.composer {
    flex: 1;
    min-width: 0;
    max-width: 760px;
    max-height: 30rem;
    transition: max-width 0.5s var(--ease-out), max-height 0.5s var(--ease-out), opacity 0.3s var(--ease-out) 0.1s,
        transform 0.5s var(--ease-out), visibility 0s;
}

/* the message box is only for home, chats and tests, and a chat. elsewhere it fades and shrinks away,
   and the tabs glide to the middle as it goes, then back when it returns */
.is-reminders .composer,
.is-performance .composer,
.is-account .composer,
.is-leaderboard .composer,
.is-study .composer {
    max-width: 0;
    opacity: 0;
    transform: translateX(24px);
    overflow: hidden;
    visibility: hidden;
    pointer-events: none;
    transition: max-width 0.5s var(--ease-out), max-height 0.5s var(--ease-out), opacity 0.2s ease-in,
        transform 0.5s var(--ease-out), visibility 0s 0.5s;
}

.dock {
    transition: gap 0.5s var(--ease-out);
}

.is-reminders .dock,
.is-performance .dock,
.is-account .dock,
.is-leaderboard .dock,
.is-study .dock {
    gap: 0;
}

.composer-box {
    position: relative;
    padding: 4px;
    border-radius: 26px;
    background: var(--dock-bg);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    box-shadow: inset 0 0 0 1px var(--dock-line), 0 10px 30px var(--shadow);
    transition: box-shadow var(--dur) var(--ease-out);
}

/* the box is focused whenever a page opens, so its ring only brightens a little and the accent stays for actions */
.composer-box:focus-within,
.composer-box.dragging {
    box-shadow: inset 0 0 0 1px var(--dock-line-focus), 0 10px 30px var(--shadow);
}

/* side by side on wider screens the tabs and message box are the same height, contents centred */
@media (min-width: 721px) {
    .tabs {
        height: 50px;
    }

    .composer-box {
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-height: 50px;
    }
}

.composer-box.dragging {
    outline: 2px dashed var(--accent);
    outline-offset: -2px;
}

/* a small chip in the message box for a mode that's on, like hint mode */
.composer-chips {
    display: flex;
    gap: 0.35rem;
}

.composer-chips:not(:empty) {
    padding: 0.35rem 0.5rem 0.1rem;
}

.composer-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.2rem 0.3rem 0.2rem 0.75rem;
    border-radius: var(--pill);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: 0.78rem;
    font-weight: 600;
}

.composer-chip button {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: var(--pill);
    color: inherit;
}

.composer-chip svg {
    width: 13px;
    height: 13px;
}

.input-option.on .opt-icon {
    background: var(--accent-fill);
    color: var(--on-accent);
}

.attachments {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.attachments:not(:empty) {
    padding: 0.4rem 0.5rem 0.3rem;
}

.composer-row {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.composer-row.tall {
    align-items: flex-end;
}

.composer .tools-btn {
    width: 36px;
    height: 36px;
}

.composer textarea {
    flex: 1;
    min-width: 0;
    max-height: 220px;
    /* one line of text is exactly as tall as the 36 pixel buttons beside it */
    padding: calc((36px - 1.5em) / 2) 0.25rem;
    border: none;
    outline: none;
    resize: none;
    background: transparent;
    font-size: 0.98rem;
    line-height: 1.5;
}

.composer textarea::placeholder {
    color: var(--text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.send-btn {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: var(--pill);
    background: var(--accent-fill);
    color: var(--on-accent);
    box-shadow: 0 3px 10px var(--glow);
    transition: opacity 0.2s, background-color 0.2s, transform var(--dur) var(--ease-out);
}

.send-btn:hover:not(:disabled) {
    background: var(--accent-fill-hover);
    transform: translateY(-2px);
}

/* while an answer comes in the send button is a stop button, a square on a quiet circle */
.send-btn.stop {
    background: var(--dock-active);
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--dock-line-focus);
}

.send-btn.stop:hover {
    background: var(--surface-2);
    transform: none;
}

/* with nothing to send the button goes quiet grey rather than a faded accent */
.send-btn:disabled:not(.stop) {
    background: var(--dock-active);
    color: var(--text-2);
    cursor: default;
}

.disclaimer {
    margin: 0.35rem auto 0.5rem;
    padding: 0 1rem;
    text-align: center;
    font-size: 0.68rem;
    color: var(--text-2);
}

@keyframes rise {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

@keyframes fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* motion, everything eases out and plays once */

/* headings, rows and cards fade up the first time they scroll into view */
.reveal:not(.shown),
.reveal-row:not(.shown) .row-title,
.reveal-row:not(.shown) .row-track > *,
.reveal-grid:not(.shown) > * {
    opacity: 0;
}

.reveal.shown,
.reveal-row.shown .row-title {
    animation: fade-up 0.6s var(--ease-out) backwards;
}

.reveal-row.shown .row-track > *,
.reveal-grid.shown > * {
    animation: fade-up 0.6s var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 60ms + 40ms);
}

.row-track > :nth-child(2), .card-grid > :nth-child(2) { --i: 1; }
.row-track > :nth-child(3), .card-grid > :nth-child(3) { --i: 2; }
.row-track > :nth-child(4), .card-grid > :nth-child(4) { --i: 3; }
.row-track > :nth-child(5), .card-grid > :nth-child(5) { --i: 4; }
.row-track > :nth-child(n + 6), .card-grid > :nth-child(n + 6) { --i: 5; }

/* the pages settle on a row as you scroll down */
.is-page .thread {
    scroll-snap-type: y proximity;
}

.is-page .row,
.is-page .category-title,
.is-page .group-title,
.is-page .perf-card {
    scroll-snap-align: start;
    scroll-margin-top: 0.5rem;
}

/* the first thing on each page is the first stop, so the page stays at the top when it loads */
.is-page .greeting,
.is-page .list-page,
.is-page .performance {
    scroll-snap-align: start;
    scroll-margin-top: 2rem;
}

/* buttons give a small squeeze when pressed */
.icon-btn,
.tab,
.choice,
.option {
    transition-property: background-color, color, border-color, opacity, transform;
    transition-duration: 0.15s;
    transition-timing-function: var(--ease-out);
}

.btn:active:not(:disabled),
.icon-btn:active:not(:disabled),
.send-btn:active:not(:disabled),
.option:active:not(:disabled),
.tab:active,
.choice:active,
.tile:active {
    transform: scale(0.96);
    transition-duration: 0.1s;
}

.row-arrow:active {
    transform: translateY(-50%) scale(0.92);
}

/* a faint line under the top bar once the page has scrolled */
.nav {
    position: relative;
    z-index: 5;
    transition: box-shadow 0.35s var(--ease-out);
}

.nav.scrolled {
    box-shadow: 0 1px 0 var(--border), 0 12px 24px -20px var(--shadow);
}

/* quiz feedback and results ease in */
#quiz-feedback > * {
    animation: fade-up 0.45s var(--ease-out) backwards;
}

#quiz-feedback > * + * {
    animation-delay: 0.08s;
}

.quiz-results {
    animation: fade-up 0.6s var(--ease-out) backwards;
}

/* switching between light and dark cross fades */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 0.3s;
    animation-timing-function: var(--ease-out);
}

@keyframes fade-up {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}

/* phones and small tablets */
@media (max-width: 720px) {
    /* phones get the whole app a size smaller, so it reads like a small copy of the website
       nearly every size is in rem, so one base size scales text and spacing together */
    :root {
        --gutter: 16px;
        font-size: 87.5%;
    }

    /* the few fixed size pieces shrink to match */
    .tile {
        width: 165px;
    }

    .chat-card {
        width: 165px;
    }

    .row-track .reminder-card {
        width: 240px;
    }

    .card-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.7rem;
    }

    .card-grid.reminder-grid {
        grid-template-columns: 1fr;
    }

    /* cards are narrow on a phone, so a title gets two lines and the details wrap instead of being cut */
    .chat-card-text strong {
        white-space: normal;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        line-height: 1.3;
    }

    /* the details and the time each get their own line, so the dot between them goes */
    .card-meta {
        flex-direction: column;
        white-space: normal;
    }

    .card-meta .meta-what {
        overflow: visible;
    }

    .card-meta .meta-dot {
        display: none;
    }

    .gpa-list .gpa-track {
        flex-basis: 3.5rem;
    }

    .sketch {
        top: 0.6rem;
        right: 0.65rem;
        width: 40px;
        height: 40px;
    }

    .play {
        width: 40px;
        height: 40px;
    }

    .play svg {
        width: 16px;
        height: 16px;
    }

    /* small print still needs to be readable. it sits low, in the top of the strip phones keep for the home bar,
       so the bar reaches the bottom of the screen with no empty band under it */
    .disclaimer {
        margin-bottom: 0.15rem;
        font-size: 11px;
    }

    .dock-wrap {
        padding-bottom: max(0.15rem, calc(env(safe-area-inset-bottom) - 1.25rem));
    }

    .sheet {
        margin: auto auto 0;
        width: 100%;
        max-width: 100%;
        border-radius: 18px 18px 0 0;
        transform: translateY(100%);
    }

    .sheet[open].closing {
        transform: translateY(100%);
    }

    @starting-style {
        .sheet[open] {
            transform: translateY(100%);
        }
    }

    .field-row,
    .perf-grid {
        grid-template-columns: 1fr;
    }

    .bar-row {
        grid-template-columns: minmax(80px, 7rem) 1fr;
    }

    .kpis {
        grid-template-columns: 1fr 1fr;
        gap: 0.6rem;
    }

    .kpis .stat-card {
        min-height: 0;
        padding: 0.85rem 0.95rem;
    }

    .kpis .stat-value {
        font-size: 1.5rem;
    }

    .kpis .stat-value.small {
        font-size: 1.05rem;
    }

    .face {
        padding: 2.5rem 1.4rem 1.5rem;
    }

    .face-text,
    .quiz-question {
        font-size: 1.15rem;
    }

    .nav {
        gap: 0.6rem;
        padding: 0.75rem var(--gutter) 0.5rem;
        padding-top: max(0.75rem, env(safe-area-inset-top));
    }

    /* in a chat the title follows the back arrow on the left, so a long one has room and stops with dots */
    body:not(.is-page) .nav {
        grid-template-columns: auto minmax(0, 1fr) auto;
        gap: 0.35rem;
    }

    body:not(.is-page) .nav-title {
        text-align: left;
        font-size: 1.05rem;
    }

    body:not(.is-page) .mode-picker .picker-btn {
        max-width: 132px;
    }

    .brand {
        font-size: 1.45rem;
    }

    .nav-title {
        font-size: 1.1rem;
    }

    .nav-right {
        gap: 0.15rem;
    }

    .mode-picker .picker-btn {
        min-width: 0;
        max-width: 150px;
        padding-left: 0.9rem;
        font-size: 0.8rem;
    }

    .picker-menu {
        grid-template-columns: minmax(12rem, 1fr);
    }

    .thread {
        padding: 0.75rem 1rem;
    }

    .dock {
        gap: 0.4rem;
        padding: 0.4rem 0.75rem 0;
    }

    .tab {
        min-width: 0;
        padding: 0.55rem 0.65rem;
    }

    .tab span {
        display: none;
    }

    .message.assistant {
        padding: 0.9rem 1.05rem 1rem;
    }

    /* the message box gets the whole width, with the tabs in a full row underneath */
    .dock {
        flex-direction: column-reverse;
        align-items: stretch;
        gap: 0.5rem;
    }

    .composer {
        max-width: none;
    }

    .is-reminders .composer,
    .is-performance .composer,
    .is-account .composer,
    .is-leaderboard .composer,
    .is-study .composer {
        max-width: none;
        max-height: 0;
        transform: translateY(12px);
    }

    .tabs {
        justify-content: space-around;
    }

    .tab {
        flex: 1;
    }

    .tab-badge {
        right: calc(50% - 22px);
    }

    /* the tab bar already says which page this is, so the header keeps its room for the wordmark and picker */
    body.is-page .nav-title {
        visibility: hidden;
    }

    .tile .sketch {
        width: 40px;
        height: 40px;
    }
}

/* iphones zoom the page into any text box under 16 pixels, so typing spots keep 16 there */
@supports (-webkit-touch-callout: none) {
    @media (max-width: 720px) {
        input,
        textarea,
        select {
            font-size: 16px !important;
        }
    }
}

/* fingers need bigger targets than a mouse, 44 pixels square */
@media (pointer: coarse) {
    .chat-card .icon-btn,
    .reminder-actions .icon-btn,
    .class-row .icon-btn,
    .picker-remove {
        width: 44px;
        height: 44px;
    }

    .send-btn,
    .composer .tools-btn {
        width: 40px;
        height: 40px;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation: none !important;
        transition: none !important;
        scroll-behavior: auto !important;
    }
}

/* the picture on the account card, tap it or its pen to choose a new one */
.face-edit {
    position: relative;
    flex-shrink: 0;
    cursor: pointer;
}

.face-pen {
    position: absolute;
    right: -4px;
    bottom: -4px;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--card-bg);
    box-shadow: 0 0 0 1.5px var(--panel-line), 0 2px 6px var(--shadow);
}

.face-pen svg {
    width: 12px;
    height: 12px;
    fill: none;
    stroke: var(--text);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.face-edit:hover .face-pen,
.face-edit:focus-within .face-pen {
    background: var(--accent-soft);
}

/* pro or max beside rahah's name at the top */
.nav-tier .pro-badge {
    margin-left: 0.45rem;
    font-size: 0.9rem;
    vertical-align: 0.15em;
}

/* the rahah logo on the install card */
.toast-logo {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 10px;
}

/* the install steps can take two lines on a phone */
.install-toast .toast-text span {
    white-space: normal;
}

.upgrade-toast .toast-text span {
    white-space: normal;
}

/* cropping a profile photo: the photo in a square, a circle showing what will be kept */
.crop-stage {
    position: relative;
    width: min(100%, 340px);
    aspect-ratio: 1;
    margin: 0 auto;
    overflow: hidden;
    border-radius: var(--card);
    background: #0e1014;
    touch-action: none;
    cursor: grab;
    user-select: none;
}

.crop-stage:active {
    cursor: grabbing;
}

.crop-stage img {
    position: absolute;
    top: 0;
    left: 0;
    max-width: none;
    transform-origin: 0 0;
    pointer-events: none;
}

.crop-ring {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    box-shadow: 0 0 0 999px rgba(5, 8, 14, 0.55), inset 0 0 0 2px rgba(255, 255, 255, 0.85);
    pointer-events: none;
}

.crop-hint {
    margin: 0.7rem 0 0.3rem;
    text-align: center;
}

.crop-zoom {
    display: block;
    width: min(100%, 340px);
    margin: 0 auto 0.4rem;
    accent-color: var(--accent-text);
}

/* the pen beside a sent question, shown on hover on a computer and always on a phone */
.bubble-row {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.25rem;
    width: 100%;
}

.bubble-row[hidden] {
    display: none;
}

.edit-question {
    display: none;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    opacity: 0;
    transition: opacity 0.15s;
}

.edit-question svg {
    width: 15px;
    height: 15px;
}

.message.user.saved .edit-question {
    display: grid;
}

.message.user.saved:hover .edit-question,
.edit-question:focus-visible {
    opacity: 1;
}

@media (hover: none) {
    .message.user.saved .edit-question {
        opacity: 0.7;
    }
}

/* the box a question is edited in */
.edit-box {
    width: min(100%, 560px);
    align-self: flex-end;
}

.edit-box textarea {
    width: 100%;
    resize: vertical;
    border-radius: 12px;
    line-height: 1.45;
}

.edit-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.45rem;
}

/* how fast each model spends the daily limit, under its description */
.model-option .model-use {
    margin-top: 0.1rem;
    font-size: 0.72rem;
    color: var(--accent-text);
}

/* the admin's code step replaces the sign in form */
.auth-card.two-step #auth-form,
.auth-card.two-step #auth-providers,
.auth-card.two-step .auth-switch,
.auth-card.two-step .auth-shared-note {
    display: none !important;
}

.two-step-back {
    margin-top: 0.8rem;
    align-self: center;
}

/* on the students page, the plan a student is on and how much of it they've used, and giving them one */
.admin-pass {
    color: var(--accent-text) !important;
}

/* how much of a student's pass is used, a slim bar under the pass name */
.admin-pass-bar {
    display: block;
    max-width: 14rem;
    margin-top: 0.3rem;
}

.admin-give {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.admin-give select {
    width: auto;
    padding: 0.35rem 0.8rem;
    font-size: 0.8rem;
}

/* female or male, for reading answers aloud, in the model menu */
.voice-row {
    cursor: default;
}

.voice-pick {
    display: inline-flex;
    flex-shrink: 0;
    padding: 0.2rem;
    border-radius: 999px;
    box-shadow: inset 0 0 0 1px var(--panel-line);
}

.voice-pick button {
    padding: 0.3rem 0.75rem;
    border: 0;
    border-radius: 999px;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-2);
    background: none;
    cursor: pointer;
}

.voice-pick button.on {
    color: var(--on-accent);
    background: var(--accent-fill);
}

/* picking pages of a long pdf, from its pill above the message box */
.file-pill .pill-pages {
    padding: 0.1rem 0.55rem;
    border-radius: var(--pill);
    font: inherit;
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--accent-text);
    box-shadow: inset 0 0 0 1px var(--panel-line);
}

.file-pill.pick {
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--accent-text);
}

.pages-count {
    min-height: 1.2em;
    margin-top: 0.4rem;
}

.pages-count.bad {
    color: var(--mauve-text);
}

/* the promo slides on the right half, a 3d stack like the certificates in runie's portfolio.
   positions come from slides.js so every move can be animated */
.slides {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    padding: 0 72px 0 24px;
}

/* the cards keep the slides' own shape, so every slide shows whole */
.slide-deck {
    position: relative;
    width: min(100%, 780px);
    aspect-ratio: 16 / 9;
    perspective: 1400px;
    cursor: pointer;
}

.slide-card {
    position: absolute;
    inset: 0;
    border-radius: 12px;
    overflow: hidden;
    background: var(--surface);
    box-shadow: 0 22px 44px -18px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.12);
    backface-visibility: hidden;
    transform-origin: 50% 50%;
}

.slide-card img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    pointer-events: none;
}

.slide-hint {
    font-size: 0.78rem;
    color: var(--text-2);
}
