/* Parent-dashboard-only styles. Shared theme and components live in OrngeEdu.UI (ornge.css). */

/* ─── The shell ───
   The menu down the side folds to a strip of icons (shell.js, and "The menu, folded" in ornge.css) and
   has headings, because sixteen pages in one unbroken list is a list you read from the top every time.
   It scrolls if the window is too short for it, which on a small laptop it is. */
.shell .sidenav { overflow-y: auto; scrollbar-width: thin; gap: .1rem; padding-top: 1rem; }
.shell .navlink { padding: .45rem .75rem; }
/* The icons are line drawings in the link's own colour: muted, and the accent on the page you are on.
   Only an emoji still standing in for an icon the set hasn't got needs a solid colour of its own - an
   emoji is drawn as see-through as the text colour it sits in, which on a light theme washes it out. */
.shell .navlink .ico .i-emoji { color: var(--text-primary); }
.nav-button { border: 0; border-left: 3px solid transparent; background: none; width: 100%; font-family: inherit; text-align: left; cursor: pointer; }
.nav-group { margin: .85rem .75rem .2rem; font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
/* In the strip a heading is a line between one group of icons and the next. */
html.nav-rail .nav-group { height: 1px; margin: .45rem .5rem; overflow: hidden; background: var(--card-border); font-size: 0; }
html.nav-rail .shell .sidenav { scrollbar-width: none; }
/* Opened out over the page rather than beside it (a window too narrow for the column). The page keeps
   the strip's width as a margin, so nothing underneath moves when the menu opens or shuts. */
html.nav-over .shell .sidenav { position: fixed; top: 0; bottom: 0; left: 0; z-index: 60; box-shadow: 14px 0 40px rgba(0, 0, 0, .5); }
html.nav-over .shell .main { margin-left: 4.1rem; }

/* ─── Go to… ───
   The box at the top of the menu (JumpTo), for when you know what you want and not which heading keeps it.
   Its answers sit in the flow and push the menu down rather than floating over it: the menu is a column
   that scrolls, and a panel hanging out of a scrolling column is a panel with its bottom cut off. Gone
   when the menu is folded to a strip of icons and on a phone's bottom bar - no room for a box in either,
   and on a phone the keyboard would cover the answers anyway. Still there when the menu is opened out over
   the page, which is the full column at a narrow window. */
/* The menu is a flex column, and a flex item shrinks: without this the answers were squeezed back
   into the height of the box alone and drawn straight over Today, Week and Lessons. */
.jump-slot { flex: 0 0 auto; min-height: 2.3rem; }
.jump { margin: .1rem .75rem .5rem; }
.jump-box {
    width: 100%; padding: .4rem .6rem; font-family: inherit; font-size: .9rem; color: var(--text);
    border: 1px solid var(--card-border); border-radius: var(--radius); background: var(--surface-2);
}
.jump-box::placeholder { color: var(--text-muted); }
.jump-results { display: flex; flex-direction: column; gap: .1rem; margin-top: .35rem; }
.jump-hit {
    display: flex; align-items: center; gap: .5rem; padding: .35rem .5rem; font-size: .88rem;
    color: var(--text); text-decoration: none; border-radius: var(--radius-sm);
}
.jump-hit:hover, .jump-hit:focus-visible { background: rgba(var(--accent-rgb), .07); }
.jump-hit .ico { width: 1.3rem; text-align: center; }
.jump-hit .i-emoji { color: var(--text-primary); }
.jump-where { margin-left: .35rem; color: var(--text-muted); font-size: .78rem; }
/* Which key to press, on the one it would take you to. */
.jump-key { margin-left: auto; padding: 0 .3rem; font-size: .64rem; color: var(--text-muted); border: 1px solid var(--card-border); border-radius: var(--radius-sm); }
.jump-none { margin: .4rem .5rem; font-size: .82rem; }
.jump-none .muted { display: block; margin-top: .15rem; font-size: .78rem; }
html.nav-rail .jump-slot { display: none; }

/* A page is held to a width it can be read at and sits in the middle of the window. It used to be
   1200px against the left edge, which on a wide monitor was a column of dashboard and a third of a
   screen of nothing. A page that is a board rather than something read asks for more with .page-board. */
.shell .main { max-width: none; padding: 1.75rem clamp(1rem, 3vw, 3rem) 4rem; }
.shell .main > .inner { max-width: var(--page-max, 1400px); margin: 0 auto; }
.inner:has(.page-wide) { --page-max: 1560px; }
.inner:has(.page-board) { --page-max: 2000px; }
.inner:has(.settings-grid) { --page-max: 1680px; }

@media (max-width: 820px) {
    .shell .main { padding: 1.25rem 1rem 6rem; }
    .shell .sidenav { overflow: visible; padding-top: .35rem; gap: .2rem; }
    .shell .navlink { padding: .35rem .4rem; }
    .shell .nav-more-panel .navlink { padding: .6rem .7rem; }
    .shell .nav-more-head { grid-column: 1 / -1; margin: .45rem .7rem 0; font-size: .68rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
    .shell .nav-more-head:first-child { margin-top: .1rem; }
    /* The number waiting sits on the corner of its icon, as it would on a phone's own home screen. */
    .shell .sidenav > .navlink { position: relative; }
    .shell .sidenav > .navlink .nav-count { position: absolute; top: .1rem; left: calc(50% + .35rem); margin: 0; padding: 0 .32rem; font-size: .62rem; }
    .jump-slot { display: none; }
}

/* ─── Type ───
   The rule is in ornge.css ("Two kinds of type"): the reading face for what is read and typed, the
   display faces for what is glanced at. These are the hub's sizes, and the pieces only the hub has. */
.shell .main { font-size: .97rem; }
.shell .main :where(th, .tt-slot .n, .theme-option, .checkbox, .tab-count, .kicker, .day-date) { font-family: var(--font-sans); }
.shell .main :where(.btn, .tab) { font-size: 1.03rem; }
.shell .main .btn-sm { font-size: .9rem; }
.shell .main :where(.small) { font-size: .86rem; }

/* ─── Putting cards on a page ───
   A column of cards with the same gap between every one, whatever each brings with it - and a card that
   decided not to appear (nothing to mark, nothing asked for) leaves no gap behind. */
.stack { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.stack > .card { margin: 0; }

/* Today: the day on the left, what is checked rather than read on the right. One column when the page
   is too narrow for two. */
.dash { display: grid; gap: 1rem; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); align-items: start; }
@container page (max-width: 899px) { .dash { grid-template-columns: 1fr; } }

/* What is happening this minute. The stripe is the colour of the period that is running. */
.now { position: relative; overflow: hidden; padding-left: 1.7rem; }
.now::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 6px; background: var(--c, var(--accent)); }
.kicker { font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.now h2 { font-family: var(--font-display); font-size: 1.45rem; margin: .3rem 0 .2rem; }
.now .detail { margin: 0; color: var(--text-secondary); }
.now .btn { margin-top: .9rem; }

.device-line { margin-top: .4rem; }
.device-line + .device-line { margin-top: .7rem; padding-top: .7rem; border-top: 1px solid var(--card-border); }
.device-name { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.list-item .done { text-decoration: line-through; color: var(--text-muted); }

/* ─── A delete that asks first (ConfirmDelete) ───
   In a drawer's footer the question takes a line of its own and Cancel and Save drop below it. The
   footer is only as wide as the drawer, and squeezed in beside them the question wrapped to three
   words a line. */
.drawer-foot { flex-wrap: wrap; }
.drawer-foot > .confirm-ask { flex: 1 1 100%; margin-bottom: 0; }

/* A logged activity: asking turns the row into two lines rather than shoving the title out of it. */
.activity-row { flex-wrap: wrap; row-gap: .4rem; }
.activity-row > .confirm-ask { margin-left: auto; }

/* ─── A period of the day (PeriodRow) ───
   The row itself is in ornge.css and her portal draws its day from it too, so what the hub does
   differently is said here and only for the hub. A lesson's title is the link and is allowed two lines:
   it used to be cut off at one, which in the week planner left a column of "Reading: A Christ…". Breaks
   and lunch are a single quiet line with the time they start. */
.shell .period { grid-template-columns: 3.3rem 4px minmax(0, 1fr) auto; }
.shell .period .time span { display: block; }
.shell .period .name { display: block; color: inherit; text-decoration: none; line-height: 1.3; overflow-wrap: anywhere; }
.shell .period a.name:hover { color: var(--accent); }
.shell .period .sub { margin-top: .1rem; font-size: .86rem; color: var(--text-muted); }
.shell .period .state { display: flex; align-items: center; gap: .4rem; }
.shell .period.is-soft { padding-top: .3rem; padding-bottom: .3rem; }
.shell .period.is-soft .time span + span { display: none; }
.shell .period.is-soft .name { font-size: .92rem; }

/* ─── The week planner: a board ───
   Every day side by side when there is room, so the week reads across as well as down. Narrower than
   that it is three, two, then one to a row. A week with a weekend in it needs a much wider page before
   seven fit. */
.week-board { --cols: 1; display: grid; gap: 1rem; align-items: start; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); }
.week-board > .card { margin: 0; padding: 1rem; container: day / inline-size; }
@container page (min-width: 560px) { .week-board { --cols: 2; } }
@container page (min-width: 820px) { .week-board { --cols: 3; } }
@container page (min-width: 1040px) { .week-board { --cols: var(--days, 5); gap: .75rem; } .week-board.weekend { --cols: 4; } }
@container page (min-width: 1750px) { .week-board.weekend { --cols: 7; } }
.day .card-head { margin-bottom: .35rem; }
.day .card-head h2 { font-size: 1.12rem; }
.day-date { margin-left: .2rem; font-size: .9rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.day .period.is-now { margin: 0 -1rem; padding-left: 1rem; padding-right: 1rem; }
/* A day that is a narrow column: the time goes above the title rather than beside it, which gives the
   title the whole width to wrap in. */
@container day (max-width: 21rem) {
    .shell .period {
        grid-template-columns: 4px minmax(0, 1fr) auto; grid-template-areas: "bar time state" "bar what what";
        gap: .15rem .6rem; align-items: start;
    }
    .shell .period .bar { grid-area: bar; }
    .shell .period .time { grid-area: time; align-self: center; }
    .shell .period .time span { display: inline; }
    .shell .period .time span + span::before { content: "–"; }
    .shell .period .what { grid-area: what; }
    .shell .period .state { grid-area: state; justify-self: end; }
    .shell .period .name { font-size: 1rem; }
    .shell .period.is-soft { grid-template-columns: 4px auto minmax(0, 1fr); grid-template-areas: "bar time what"; align-items: center; }
    .shell .period.is-soft .state { display: none; }
}

/* ─── A lesson with work to mark: a desk ───
   What you mark against on one side and what she did on the other. The lesson's side stays where it is
   while her work scrolls with the page, and scrolls on its own if the plan is longer than the window -
   so the answer to question 19 can be beside question 19. Too narrow for two and they are one after the
   other: her work first when it is finished and waiting, the plan first otherwise. */
.marking { display: flex; flex-direction: column; gap: 1rem; }
.marking > .card { margin: 0; min-width: 0; }
.marking.work-first > .pane-work { order: -1; }
/* ...and then there is nothing below to be sent down to. */
.alert:has(+ .marking.work-first) .only-stacked { display: none; }
.pane-guide > .tabs { margin: -.4rem 0 1rem; }
.pane-work { scroll-margin-top: 1rem; }
@container page (min-width: 1050px) {
    .marking { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
    .marking.work-first > .pane-work { order: 0; }
    .pane-guide { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; scrollbar-width: thin; }
    /* The link down to her work is for when it is below. Here it is alongside. */
    .only-stacked { display: none; }
}

/* Side by side with not much to spare (a 1280 laptop with the menu folded): a little less padding in
   each side buys the plan the last few characters an answer key needs to stay in its columns. */
@container page (min-width: 1050px) and (max-width: 1220px) {
    .marking { gap: .75rem; }
    .marking > .card { padding: 1rem; }
}

/* Cards inside a card (the "About it" tab): the same things, without a second frame round them. */
.flat > .card { padding: 0; border: 0; background: none; box-shadow: none; }
.flat > .card + .card { padding-top: 1rem; border-top: 1px solid var(--card-border); border-radius: 0; }

/* ─── Write it, or see how it will look (WritePreview) ─── */
.write-preview > .tabs { margin-bottom: .75rem; }
.write-preview > .tabs .tab { padding: .35rem .8rem; }

/* Her instructions as her portal shows them (StepsPreview): the number, then the step. */
.steps-preview > * + * { margin-top: .6rem; }
.steps-preview .step { display: grid; grid-template-columns: 2rem minmax(0, 1fr); gap: .5rem; }
.steps-preview .step-n { font-family: var(--font-sans); font-size: 1.05rem; font-weight: 700; color: var(--accent); text-align: center; }
.steps-preview .step-text { line-height: 1.6; white-space: pre-line; }
.steps-preview .step-words { margin: 0; line-height: 1.65; white-space: pre-wrap; }

/* A plan or a set of instructions, set out as a page (ReadingPage). The box is what its type is sized
   against, so it has to be something that knows its own width. */
.read-box { container-type: inline-size; }
.read-box.boxed { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .85rem 1rem; }
.read-box .read-bar { margin: -.25rem 0 .25rem; }
/* A little smaller than in her portal before it gives up and wraps: an answer key is a table, and a
   table that has wrapped is not one. */
.shell .reading { font-size: clamp(.7rem, 2.02cqi, .92rem); }

/* ─── Typing ───
   A box grows with what is in it, up to most of the window, and scrolls after that: a lesson plan used
   to be read through a slot twenty lines tall. Where the browser cannot do that it is the height it
   always was. */
.shell textarea { field-sizing: content; max-height: 75vh; line-height: 1.55; }
/* Plans, instructions and readings are plain text set out with spaces - an answer key in columns, a
   step and what hangs under it - and her portal sets them out by counting those spaces. So they are
   typed in a face where a space is as wide as a letter, and what lines up here lines up there. */
textarea.typed { font-family: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace; font-size: .86rem; line-height: 1.6; tab-size: 4; }

/* ─── A plain table of rows (screen time) ─── */
.table { width: 100%; border-collapse: collapse; }
.table td { padding: .4rem .5rem; border-top: 1px solid var(--card-border); vertical-align: top; }
.table tr:first-child td { border-top: 0; }
.table td:first-child { padding-left: 0; }
.table td:last-child { padding-right: 0; }
/* The name takes what the bar and the time leave, and is cut short rather than wrapping its icon onto
   a line of its own. What it was cut from is in the tooltip. */
.usage { table-layout: fixed; }
.usage td { overflow-wrap: anywhere; }
.usage .app { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.usage .share { width: 30%; vertical-align: middle; }
.usage .when { width: 3.4rem; font-family: "Share Tech Mono", ui-monospace, monospace; font-size: .85rem; }
/* How long. Given a width of its own so that a page title with no spaces in it (an address, usually)
   wraps inside its own column instead of pushing this one off the side of the card. */
.usage td.right { width: 6.2rem; }

/* A run's end time under its start, smaller. */
.usage .when .until { display: block; font-size: .78rem; opacity: .8; }

/* ─── Screen time, a bar for each day ─── */
.days { display: flex; flex-direction: column; gap: .15rem; }
.day-row {
    display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) 6.5rem; align-items: center; gap: .75rem;
    width: calc(100% + 1rem); padding: .3rem .5rem; margin: 0 -.5rem;
    font: inherit; color: inherit; text-align: left; cursor: pointer;
    background: none; border: 0; border-radius: var(--radius-sm);
}
.day-row:hover { background: rgba(var(--accent-rgb), .07); }
.day-row.on { background: var(--brand-soft); }
.day-row.on .day-name { color: var(--accent); font-weight: 700; }
.day-name { font-family: var(--font-sans); font-weight: 600; white-space: nowrap; }
.day-total { text-align: right; white-space: nowrap; color: var(--text-secondary); }
.day-bar { display: flex; height: .7rem; border-radius: 999px; overflow: hidden; background: var(--card-border); }
.day-bar .part { height: 100%; }
.day-bar .laptop, .key-laptop { background: var(--accent); }
.day-bar .phone, .key-phone { background: color-mix(in srgb, var(--accent) 45%, var(--text-muted)); }
.key { display: inline-block; width: .7rem; height: .7rem; border-radius: 3px; vertical-align: middle; margin-left: .5rem; }
@media (max-width: 520px) { .day-row { grid-template-columns: 4.6rem minmax(0, 1fr) 5.2rem; gap: .5rem; } }

/* ─── Problems her devices reported (Settings) ─── */
.problem { padding: .7rem 0; border-top: 1px solid var(--card-border); overflow-wrap: anywhere; }
.problem:first-child { border-top: 0; }
.problem-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .1rem .75rem; margin-bottom: .2rem; }
.problem summary { cursor: pointer; margin-top: .2rem; }
.problem pre { margin: .4rem 0 0; max-height: 20rem; overflow: auto; white-space: pre-wrap; font-size: .75rem; }

/* The facts under a page title — "Maths · Monday 28 September · 10:00–11:00" — separated without markup. */
.lesson-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0; }
.lesson-meta > span + span::before { content: "·"; margin-right: .5rem; color: var(--text-muted); }
.lesson-meta > .subject-dot + span::before { content: none; margin: 0; }

/* Long written text: line breaks kept, and held to a readable line length however wide the window is. */
.prose { white-space: pre-wrap; font-size: 1.02rem; line-height: 1.65; color: var(--text-secondary); max-width: 78ch; }
.prose.boxed { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .85rem; }

/* A main column with a narrower rail beside it, rather than two equal halves. */
.grid-side { grid-template-columns: minmax(0, 1fr) minmax(0, 360px); }
@media (max-width: 1080px) { .grid-side { grid-template-columns: 1fr; } }

/* ─── The list of lessons ───
   A row is one link from edge to edge. A day's heading sits above the lessons on it. */
.lesson-list > li { border-top: 1px solid var(--card-border); }
.lesson-list > li:first-child, .lesson-list > .day-head, .lesson-list > .day-head + li { border-top: 0; }
.lesson-list > .day-head {
    padding: 1.1rem 0 .3rem; font-family: var(--font-sans); font-size: .8rem; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted);
}
.lesson-list > .day-head:first-child { padding-top: .35rem; }
.lesson-row {
    display: flex; align-items: center; gap: .85rem; margin: 0 -.6rem; padding: .65rem .6rem;
    border-radius: var(--radius-sm); color: inherit; text-decoration: none;
}
.lesson-row:hover { background: rgba(var(--accent-rgb), .07); color: inherit; }
.lesson-row:hover strong { color: var(--accent); }
.lesson-row .grow { flex: 1; min-width: 0; }
.lesson-row strong { display: block; }

/* Step along a run of lessons without going back to the list. */
.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; margin-top: 1.25rem; }
.pager .spacer { flex: 1; }

/* ─── The timetable ───
   The time and "every week" share a line. A break or lunch is a single line, time then name; whether it
   is every week is in its tooltip and in the panel that opens when it is pressed. */
.tt .tt-slot .t { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 .5rem; }
.tt .tt-slot .wk { opacity: .75; }
.tt .tt-slot.soft { display: flex; align-items: baseline; gap: .6rem; padding: .28rem .65rem; margin-bottom: .35rem; }
.tt .tt-slot.soft .t { display: block; }
.tt .tt-slot.soft .wk { display: none; }
.tt .tt-slot.soft .n { font-size: .9rem; font-weight: 600; color: var(--text-secondary); }

/* Which week the timetable is showing: back, the list of weeks, forward. The list takes what room
   there is, and "This week" drops underneath when there is none - it used to be told never to wrap and
   to be at least 16rem wide, which pushed the buttons off the side of a phone and, on a desktop, over
   the date box next to it. */
.week-pick select { flex: 1 1 11rem; width: auto; min-width: 0; }
/* A box that takes two columns of a form - and, when the form is down to one column, takes that. */
.span-2 { grid-column: span 2; }
@media (max-width: 520px) { .span-2 { grid-column: 1 / -1; } }

/* Three boxes on a line, one of them wider. These were written into the page as fixed thirds, so on a
   phone a subject was a box wide enough for its icon and "Done" was "Do". Here they can be told to
   become two to a line with the wide one on a line of its own. */
.cols-wide-first { grid-template-columns: 2fr 1fr 1fr; }
.cols-wide-last { grid-template-columns: 1fr 1fr 2fr; }
.cols-resource { grid-template-columns: 2fr 1fr 3fr; }
@media (max-width: 640px) {
    .cols-wide-first, .cols-wide-last, .cols-resource { grid-template-columns: 1fr 1fr; }
    .cols-wide-first > :first-child, .cols-wide-last > :last-child, .cols-resource > :last-child { grid-column: 1 / -1; }
}

/* ─── A phone ───
   Things that are fine with room and too wide without it. */
@media (max-width: 520px) {
    /* The three numbers at the top of a page: a line each, the number at the end of it, instead of
       three tall tiles to scroll past before the page starts. */
    .shell .stats { gap: .5rem; }
    .shell .stats > .stat { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 1rem; padding: .7rem 1rem; }
    .shell .stats > .stat > .value { grid-column: 2; grid-row: 1 / span 2; margin: 0; }
    .shell .stats > .stat > .value.big { font-size: 1.7rem; }
    .shell .stats > .stat > .detail { grid-column: 1; }
    /* A title is read here, not glanced at across a wide row: it wraps rather than ending in dots. */
    .shell .list-item .truncate { white-space: normal; }
    /* A reward: its name gets the line, and what it costs and the button to remove it go under it. */
    .reward-item { flex-wrap: wrap; justify-content: flex-end; row-gap: .4rem; }
    .reward-item > .grow { flex: 1 1 calc(100% - 3rem); }
    .shell .pager .btn { padding: .45rem .6rem; font-size: .88rem; }
    /* A table with boxes to type in (night mode's times): three of them across is a tight fit. */
    .shell .report-table th, .shell .report-table td { padding-left: .3rem; padding-right: .3rem; }
    .shell .report-table input, .shell .report-table select { padding: .4rem .35rem; }
}

/* Topic tick-boxes side by side instead of one long ladder down a narrow column. */
.topic-columns { columns: 250px auto; column-gap: 1.75rem; }
.topic-columns > details { break-inside: avoid; margin-bottom: .5rem; }

/* Thumbnails of the files she handed in. */
.work-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: .6rem; }
.work-item { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .5rem; background: var(--surface-2); }
.work-item:hover { border-color: var(--glass-border-hover); }
.work-grid a { text-decoration: none; color: inherit; display: block; }
/* The remove button only appears on hover or keyboard focus, so a wall of thumbnails is not a wall of buttons. */
.work-remove { width: 100%; margin-top: .35rem; opacity: 0; transition: opacity .15s; }
.work-item:hover .work-remove, .work-remove:focus-visible { opacity: 1; }
@media (hover: none) { .work-remove { opacity: 1; } }
.work-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; margin-top: .35rem; }
.work-grid img { width: 100%; height: 90px; object-fit: cover; border-radius: 6px; display: block; margin-bottom: .35rem; }
.work-grid .doc { height: 90px; display: grid; place-items: center; font-size: 2rem; }

/* A topic's ratings over time, oldest first: small, so a list of topics is still a list. */
.rag-trail { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .3rem; white-space: nowrap; }
.rag-step { display: inline-flex; align-items: center; gap: .2rem; }

/* A few photos of her work in the report, small enough that a page of them still prints as a page. */
.report-thumbs { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .3rem; }
.report-thumbs img { width: 72px; height: 72px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); display: block; }
@media print { .report-thumbs img { width: 1.1in; height: 1.1in; } }

/* Which child the hub is showing (only drawn once there is more than one). */
.child-switch { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0 0 1rem; }
.child-switch a.pill { text-decoration: none; }
.child-switch a.pill:hover { border-color: var(--brand); }
.child-switch > a.small { margin-left: .4rem; }

/* A page that saves with one button keeps it in view: the lesson editor's title and Save stay at the top
   while the long boxes scroll under them. "Unsaved changes" shows once anything differs from what is
   saved (hub.js notices typing at once; the page works out the rest). */
.page-head.save-bar {
    position: sticky; top: 0; z-index: 20;
    background: var(--bg); padding: .75rem 0; margin-top: -.75rem;
    border-bottom: 1px solid var(--card-border);
}
.unsaved-pill { display: none; }
[data-unsaved-watch].is-dirty .unsaved-pill { display: inline-flex; }

/* Tick boxes line up with the first line of their words (not the middle of a wrapped label), and are one
   size everywhere. File pickers look like the hub's own buttons rather than the browser's grey default. */
.shell .main .checkbox { align-items: flex-start; }
.shell .main .checkbox > input[type=checkbox] { flex: none; width: 1.05rem; height: 1.05rem; margin: .18em 0 0; }
.shell .main input[type=file] { font: inherit; font-size: .9rem; color: var(--text-muted); max-width: 100%; }
.shell .main input[type=file]::file-selector-button {
    font: inherit; font-weight: 700; margin-right: .75rem; padding: .45rem .9rem; cursor: pointer;
    border-radius: var(--radius-sm); border: 1px solid var(--card-border); background: var(--surface-2); color: var(--text-primary);
}
.shell .main input[type=file]::file-selector-button:hover { border-color: var(--brand); }

/* ─── Explanations (Explain) ───
   A line is kept to a line and the rest sits behind the ⓘ after it. That used to be the enclosing
   element's tooltip, which a phone has no way to show - no hover, so on the device a parent is most
   likely to be holding, the mark did nothing. It is a button now: hover still works on a computer,
   and a tap opens the text underneath. */
.shell .main .info-mark {
    color: var(--accent); font-style: normal; font: inherit; line-height: 1;
    background: none; border: 0; padding: 0 .15rem; cursor: pointer; border-radius: 4px;
}
.shell .main .info-mark:hover, .shell .main .info-mark[aria-expanded="true"] { color: var(--text); }
.shell .main .info-mark:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .2); }
.shell .main .explain-text {
    display: block; margin: .4rem 0 .2rem; padding: .45rem .7rem;
    border-left: 2px solid var(--accent); border-radius: var(--radius-sm);
    background: var(--surface-2); color: var(--text-secondary); font-weight: 400;
}
/* A few tooltips are still only tooltips: a button's title, a column heading. They say so by the cursor. */
.shell .main p[title], .shell .main .hint[title] { cursor: help; }

/* A one-line summary that opens to the detail under it (Websites' reading progress, say). */
.shell .main details.peek > summary { cursor: pointer; list-style: none; padding: .25rem 0; }
.shell .main details.peek > summary::-webkit-details-marker { display: none; }
.shell .main details.peek > summary::before { content: "▸"; display: inline-block; width: 1rem; color: var(--accent); transition: transform .15s; }
.shell .main details.peek[open] > summary::before { transform: rotate(90deg); }
.shell .main .own-window { margin: 0; white-space: nowrap; }

/* The marking desk (a lesson's Her work): a tick and a cross beside each answer, the model answer under
   hers, and your feedback kept in view at the bottom of the pane while a long sheet scrolls past. */
.desk-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.desk-q { border-left: 3px solid transparent; padding-left: .6rem; margin-left: -.6rem; }
.desk-q.is-right { border-left-color: var(--ok); }
.desk-q.is-wrong { border-left-color: var(--danger); }
.desk-q-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; }
.desk-ticks { display: inline-flex; gap: .3rem; flex: none; }
.desk-tick {
    width: 2rem; height: 2rem; display: grid; place-items: center; cursor: pointer;
    font: inherit; font-weight: 700; font-size: 1rem; line-height: 1;
    border-radius: var(--radius-sm); border: 1px solid var(--card-border); background: var(--surface-2); color: var(--text-muted);
}
.desk-tick.right:hover, .desk-tick.right.on { color: var(--ok); border-color: var(--ok); }
.desk-tick.wrong:hover, .desk-tick.wrong.on { color: var(--danger); border-color: var(--danger); }
.desk-tick.right.on { background: color-mix(in srgb, var(--ok) 18%, transparent); }
.desk-tick.wrong.on { background: color-mix(in srgb, var(--danger) 18%, transparent); }
/* Hers and the answer side by side when the pane has room for both, stacked when it hasn't. */
.desk-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .5rem .75rem; margin-top: .35rem; align-items: start; }
.desk-pair.solo { grid-template-columns: 1fr; }
.desk-label { display: block; margin-bottom: .2rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: .68rem; color: var(--text-muted); }
.desk-hers .prose.boxed { margin: 0; }
.desk-key { padding: .55rem .75rem; border-radius: var(--radius-sm); border: 1px dashed var(--card-border); white-space: pre-wrap; background: color-mix(in srgb, var(--ok) 6%, transparent); }
.desk-key.empty { background: none; }
.desk-nokeys { margin: 0 0 .5rem; }
.desk-feedback { border-top: 1px solid var(--card-border); margin-top: 1.25rem; padding-top: 1rem; }
@media (min-width: 821px) and (min-height: 640px) {
    .desk-feedback { position: sticky; bottom: 0; z-index: 5; background: var(--surface); padding-bottom: .75rem; box-shadow: 0 -12px 18px -12px rgba(0, 0, 0, .45); }
    .desk-feedback textarea { min-height: 4.5rem; max-height: 9rem; }
}
.desk-key.from-plan { border-style: dotted; opacity: .9; }

/* A worksheet question in the editor, folded to one line until it's clicked. */
.q-card .card-head { flex-wrap: wrap; }
.q-toggle { display: flex; align-items: baseline; gap: .45rem; min-width: 0; flex: 1 1 16rem; padding: .2rem 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.q-card.open .q-toggle { flex: 0 0 auto; }
.q-chevron { color: var(--accent); display: inline-block; transition: transform .15s; }
.q-card.open .q-chevron { transform: rotate(90deg); }
.q-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.q-card:not(.open) { padding-top: .55rem; padding-bottom: .55rem; }

/* Progress: a card per subject (also at the top of a subject's own page). */
.plain-link { color: inherit; text-decoration: none; }
.plain-link:hover { color: var(--accent); }
.sp-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: .45rem .9rem; margin: 0; align-items: baseline; }
.sp-rows dt { color: var(--text-muted); font-size: .85rem; }
.sp-rows dd { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .5rem; min-width: 0; }
.sp-bar { flex: 1 1 5rem; height: .45rem; border-radius: 99px; background: var(--surface-2); overflow: hidden; max-width: 10rem; }
.sp-bar > span { display: block; height: 100%; border-radius: inherit; }
.sp-rag { display: flex; flex: 1 1 5rem; max-width: 10rem; height: .45rem; border-radius: 99px; overflow: hidden; background: var(--surface-2); }
.sp-rag .g { background: #23a55a; } .sp-rag .a { background: #faa61a; } .sp-rag .r { background: #f23f43; } .sp-rag .n { background: var(--card-border); }
.sp-counts { display: inline-flex; flex-wrap: wrap; gap: .2rem .65rem; }
.subject-progress .card-head .pill { white-space: nowrap; }

/* Websites: adding a site is one row at the top of the list; on a phone the row stacks and each site's
   tick box and Remove go under its name, so the name gets the width. */
.site-add { display: grid; grid-template-columns: minmax(12rem, 2fr) minmax(10rem, 1.5fr) auto auto; gap: .5rem .75rem; align-items: end; }
.site-add .field { margin: 0; }
.site-add .checkbox { margin: 0 0 .6rem; white-space: nowrap; }
.site-globe { font-size: 1.1rem; }
.site-name { display: block; overflow-wrap: anywhere; }
.site-actions { display: inline-flex; align-items: center; gap: .75rem; flex: none; }
details.peek.card > summary { padding: 0; }
@media (max-width: 700px) {
    .site-add { grid-template-columns: 1fr; }
    .site-add .checkbox { margin: 0; }
    .site-list .list-item { flex-wrap: wrap; }
    .site-actions { width: 100%; justify-content: flex-end; }
}

/* The week as a planning board: ⇄ (or a drag) picks a lesson up; the periods it can go to light up with
   "Move here" / "Swap here"; the lesson bank folds above the board. */
.shell .period .move-btn { padding: .1rem .45rem; font-size: .95rem; }
.shell .period.is-movable { cursor: grab; }
.slot-drop { position: relative; border-radius: var(--radius-sm); }
.week-board.is-moving .slot-drop.can-take { outline: 2px dashed var(--accent); outline-offset: -2px; }
.slot-drop .put-here { position: absolute; right: .4rem; top: 50%; transform: translateY(-50%); z-index: 2; }
.missed-day { margin: 0 0 .5rem; }
.bank-panel { margin-bottom: 1rem; }
.bank-list { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); gap: .35rem .9rem; }
.bank-list li { display: flex; align-items: center; gap: .5rem; padding: .3rem .4rem; border-radius: var(--radius-sm); cursor: grab; min-width: 0; }
.bank-list li:hover { background: var(--surface-2); }
.bank-list li.picked { outline: 2px solid var(--accent); }
.bank-list li a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; }
.bank-list .subject-dot { flex: none; }
.move-bar { position: sticky; top: 0; z-index: 15; }

/* A row of choices, one on at a time (Revision's subjects). */
.chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 1rem; }
.chip { display: inline-flex; align-items: center; gap: .4rem; padding: .3rem .75rem; border-radius: 99px; cursor: pointer;
        border: 1px solid var(--card-border); background: var(--surface); color: inherit; font: inherit; font-size: .9rem; }
.chip:hover { border-color: var(--accent); }
.chip.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }

/* Mocks: each subject's grades in date order. */
.mock-trend-name { min-width: 9rem; }
.mock-trend-results { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.mock-trend-results .pill { cursor: pointer; border: 0; font: inherit; font-size: .85rem; }

/* Today: the lesson on now (or next), with its first objectives; devices as a line each. */
.now-goals { margin: .35rem 0 .6rem; padding-left: 1.1rem; font-size: .92rem; color: var(--text-secondary); }
.device-status.compact .device-line .detail { display: none; }
.device-status.compact .device-line { margin: .15rem 0; }

/* Re-plan's preview: the weeks the plan makes, a column a day. */
.replan-week { margin: 1rem 0 .4rem; text-transform: uppercase; letter-spacing: .05em; }
.replan-board { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .5rem; }
.replan-day { min-width: 0; }
.replan-day-head { font-weight: 700; font-size: .85rem; margin-bottom: .3rem; color: var(--text-secondary); }
.replan-lesson { display: flex; flex-direction: column; gap: .1rem; padding: .4rem .55rem; margin-bottom: .35rem; border-radius: var(--radius-sm);
                 background: var(--surface-2); border-left: 3px solid var(--c); min-width: 0; overflow-wrap: anywhere; font-size: .9rem; }
@media (max-width: 820px) { .replan-board { grid-template-columns: 1fr; } .replan-day:not(:has(.replan-lesson)) { display: none; } }

/* Answers from plans: a row per question, its answer editable, ticked to save. */
.answers-table { display: grid; gap: .3rem; }
.answers-row { display: grid; grid-template-columns: auto 2rem minmax(0, 1.2fr) minmax(0, 1fr); gap: .6rem; align-items: center; padding: .25rem 0; border-top: 1px solid var(--card-border); }
.answers-row.off { opacity: .5; }
.answers-q { overflow-wrap: anywhere; font-size: .92rem; }
.answers-a { width: 100%; }
@media (max-width: 700px) { .answers-row { grid-template-columns: auto 1.6rem minmax(0, 1fr); } .answers-a { grid-column: 2 / -1; } }

/* Her answer in its own shape on the marking desk: a table, her ticks, her drawing. */
.her-table { margin: 0; }
.her-table .report-table td, .her-table .report-table th { font-size: .9rem; }
.her-ticks { list-style: none; margin: 0; padding: .5rem .75rem; border-radius: var(--radius-sm); background: var(--surface-2); border: 1px solid var(--border); }
.her-ticks li { color: var(--text-muted); }
.her-ticks li.on { color: inherit; font-weight: 600; }
.her-sketch { width: 100%; max-width: 30rem; aspect-ratio: 3 / 2; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text-primary); }

/* Her spelling: the word as she wrote it. */
.spell-wrong { text-decoration: line-through; text-decoration-color: var(--danger); color: var(--text-secondary); }
.spell-list .list-item { padding: .3rem 0; }

/* An answer she changed after it came back crossed: flagged on the desk until you tick or cross it again,
   and counted on the To mark card. */
.desk-q.is-corrected { border-left-color: var(--warn); }
.desk-corrected { margin: 0 0 .3rem; padding: .3rem .55rem; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.tomark-corrected { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); border-color: transparent; }
