/* /Components/AppHeader.razor.rz.scp.css */
.appbar[b-1hhspwyv7q] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: none;
    height: 2.75rem;
    padding: 0 0.625rem;
    background: var(--cf-chrome);
    border-bottom: 1px solid var(--cf-border);
}

.brand[b-1hhspwyv7q] {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    flex: none;
}

.brand-mark[b-1hhspwyv7q] {
    width: 1.25rem;
    height: 1.25rem;
}

.brand-mark-dim[b-1hhspwyv7q] {
    fill: var(--cf-faint);
}

.brand-mark-lit[b-1hhspwyv7q] {
    fill: var(--cf-accent);
}

.brand-name[b-1hhspwyv7q] {
    color: var(--cf-text);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.brand-name-accent[b-1hhspwyv7q] {
    color: var(--cf-accent);
}

/* Set off from the wordmark by a rule rather than by distance, since the two are
   read together and the bar is too shallow for vertical separation to do it. */
.appbar-note[b-1hhspwyv7q] {
    margin: 0;
    padding-left: 0.75rem;
    border-left: 1px solid var(--cf-border);
    color: var(--cf-muted);
    font-size: 0.75rem;
    white-space: nowrap;
}

.appbar-spacer[b-1hhspwyv7q] {
    flex: 1;
    min-width: 0.25rem;
}

/* A round glyph button, the shape this family gives to the things that open over the
   workbench rather than change it. */
.appbar-icon[b-1hhspwyv7q] {
    display: grid;
    place-items: center;
    flex: none;
    width: 1.75rem;
    height: 1.75rem;
    border: 1px solid var(--cf-border);
    border-radius: 999px;
    background: transparent;
    color: var(--cf-muted);
    font: inherit;
    font-size: 0.8125rem;
    cursor: pointer;
}

.appbar-icon:hover[b-1hhspwyv7q] {
    background: var(--cf-chrome-hover);
    color: var(--cf-text);
}

/* The tagline is the first thing to go: it is reassurance, and the controls beside
   it are the app. */
@media (max-width: 57.59rem) {
    .appbar[b-1hhspwyv7q] {
        gap: 0.5rem;
    }

    .appbar-note[b-1hhspwyv7q] {
        display: none;
    }
}
/* /Components/FieldGrid.razor.rz.scp.css */
/* One field: its heading, then every value it could take. The hue comes in from the
   component as --hue, and is the same one the field's characters are drawn in up in the
   expression box - that pairing is the only thing tying the two together, so nothing in
   here may introduce a colour of its own. */
/* No rule underneath while the grids sit side by side: they are different heights - a field
   of seven values is shorter than one of sixty, and truthfully so - and a border would draw
   five lines at five different heights across the band. The coloured field names already
   separate the columns. It comes back when they stack; see the foot of this file. */
.grid[b-ozzpdx9wb1] {
    padding: 0.5rem 0.625rem 0.625rem;
    min-width: 0;
}

/* One line, always. `nowrap` is load-bearing rather than tidiness: this bar sits directly
   above the cells, so anything that lets it become two lines moves the cells down mid-drag,
   and a drag is exactly when the contents of a header like this change most. */
.grid-head[b-ozzpdx9wb1] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: nowrap;
    min-width: 0;
    margin-bottom: 0.375rem;
}

.grid-name[b-ozzpdx9wb1] {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    color: var(--hue);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}

.grid-spacer[b-ozzpdx9wb1] {
    flex: 1;
    min-width: 0.25rem;
}

/* A floor wide enough for the longest count the field can reach, so that going from
   "9 of 60" to "10 of 60" during a drag does not nudge the button beside it sideways. */
.grid-count[b-ozzpdx9wb1] {
    flex: none;
    min-width: 8ch;
    color: var(--cf-faint);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

/* The cells. `touch-action: none` is what lets a finger drag across them and paint
   rather than scroll the pane, and `user-select: none` stops a mouse drag turning the
   labels into a text selection halfway through. */
.grid-cells[b-ozzpdx9wb1] {
    display: grid;
    grid-template-columns: repeat(var(--cols, 10), minmax(0, 1fr));
    gap: 2px;
    touch-action: none;
    user-select: none;
}

.cell[b-ozzpdx9wb1] {
    padding: 0.25rem 0;
    border: 1px solid transparent;
    border-radius: 3px;
    background: var(--cf-chrome-2);
    color: var(--cf-faint);
    font: inherit;
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
    text-align: center;
    cursor: pointer;
}

.cell:hover:not(.is-on)[b-ozzpdx9wb1] {
    background: var(--cf-chrome-hover);
    color: var(--cf-text);
}

/* Lit. The pane colour for the ink rather than a fixed black or white: the hues are
   bright on the dark theme and dark on the light one, and the pane is the opposite of
   each - so the one token reads correctly in both. */
.cell.is-on[b-ozzpdx9wb1] {
    background: var(--hue);
    color: var(--cf-pane);
    font-weight: 600;
}

.cell.is-on:hover[b-ozzpdx9wb1] {
    background: color-mix(in srgb, var(--hue) 80%, var(--cf-pane));
}

/* A field matching every value is unconstrained rather than sixty things chosen, and it
   is drawn as such: washed instead of solid. The difference is not decoration - it is
   what says that clicking one of these narrows the field to it, rather than knocking a
   single value out of a set. */
.grid-cells.is-open .cell.is-on[b-ozzpdx9wb1] {
    background: color-mix(in srgb, var(--hue) 14%, transparent);
    border-color: color-mix(in srgb, var(--hue) 28%, transparent);
    color: var(--hue);
    font-weight: 400;
}

.grid-cells.is-open .cell.is-on:hover[b-ozzpdx9wb1] {
    background: var(--hue);
    border-color: var(--hue);
    color: var(--cf-pane);
    font-weight: 600;
}

.cell:focus-visible[b-ozzpdx9wb1] {
    outline: 2px solid var(--cf-accent);
    outline-offset: -1px;
}

/* Room for a fingertip - and now that the grids are stacked one above another rather than
   ranged across, a rule between them is what says where one ends and the next begins. */
@media (max-width: 57.59rem) {
    .cell[b-ozzpdx9wb1] {
        padding: 0.375rem 0;
    }

    .grid[b-ozzpdx9wb1] {
        border-bottom: 1px solid var(--cf-border-soft);
    }
}
/* /Components/FieldStrip.razor.rz.scp.css */
/* The expression, and the largest thing on the page. Each box carries its field's hue -
   the same one the grid below it is drawn in - so the strip and the grids read as one
   thing without anything having to join them up. */
.strip[b-97lqiiz0fh] {
    display: flex;
    align-items: flex-start;
    gap: 0.4375rem;
}

/* Every box the same width, and that width decided by the strip rather than by what is
   in it.

   Sizing a box to its contents made it jump about as you typed, which is the one thing
   an input under a caret must not do. `flex: 1 1 0` gives them equal shares of whatever
   the strip has, so a box only ever changes width when the window does - and on a normal
   screen each share is wide enough for the longest thing anyone puts in one of these
   (`9-11,17,18,27` and the like). Below that the text scrolls inside its own box, which
   is what a text input does anyway, and the whole expression is always in the status
   bar. */
.strip-field[b-97lqiiz0fh] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1875rem;
    flex: 1 1 0;
    min-width: 0;
}

.strip-box[b-97lqiiz0fh] {
    box-sizing: border-box;
    width: 100%;
    padding: 0.3125rem 0.4375rem;
    border: 1px solid color-mix(in srgb, var(--hue) 30%, transparent);

    /* The hue is on the underline rather than around the whole box: five saturated
       outlines in a row would compete with the grids, and the underline is enough to
       pair a box with the grid that carries the same one. */
    border-bottom: 2px solid var(--hue);
    border-radius: 5px 5px 3px 3px;
    background: color-mix(in srgb, var(--hue) 8%, var(--cf-chrome-2));
    color: var(--cf-text);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-align: center;
}

.strip-box:focus[b-97lqiiz0fh] {
    outline: none;
    background: color-mix(in srgb, var(--hue) 16%, var(--cf-chrome-2));
    border-color: var(--hue);
}

.strip-box[b-97lqiiz0fh]::selection {
    background: color-mix(in srgb, var(--hue) 45%, transparent);
}

/* A field that could not be read. The box is marked rather than the whole expression,
   because exactly one of them is wrong and the message beneath names it. */
.strip-field.is-bad .strip-box[b-97lqiiz0fh] {
    border-color: var(--cf-danger);
    background: var(--cf-danger-wash);
    color: var(--cf-danger);
}

.strip-field.is-bad .strip-name[b-97lqiiz0fh] {
    color: var(--cf-danger);
}

.strip-name[b-97lqiiz0fh] {
    max-width: 100%;
    overflow: hidden;
    color: var(--hue);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}

/* What the field accepts. The one line that makes the strip usable by someone who does
   not already know which position is which. */
.strip-range[b-97lqiiz0fh] {
    max-width: 100%;
    overflow: hidden;
    color: var(--cf-faint);
    font-size: 0.625rem;
    font-variant-numeric: tabular-nums;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The boxes shrink rather than wrap: five fields on one line is what makes the strip
   read as an expression, and two lines of three is not the same object. */
@media (max-width: 57.59rem) {
    .strip[b-97lqiiz0fh] {
        gap: 0.25rem;
    }

    .strip-box[b-97lqiiz0fh] {
        padding: 0.25rem 0.1875rem;
        font-size: 1rem;
    }

    .strip-range[b-97lqiiz0fh] {
        display: none;
    }
}

/* On a phone there is no width to share out: five boxes across a 390px screen are five
   slivers, none of which can show `MON-FRI`. Two rows of three is a worse picture of an
   expression and a far better editor, and the whole expression is in the status bar for
   anyone who wants to read it as one line. */
@media (max-width: 32rem) {
    .strip[b-97lqiiz0fh] {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 0.5rem 0.375rem;
    }

    .strip-box[b-97lqiiz0fh] {
        font-size: 1.0625rem;
    }

    .strip-range[b-97lqiiz0fh] {
        display: block;
    }
}
/* /Components/LibraryOverlay.razor.rz.scp.css */
.library:not([open])[b-jy5pt5yaa4] {
    display: none;
}

/* A fixed height rather than a cap this content grows up to: a `<dialog>` recentres itself
   in the viewport whenever its box changes size, so with only `max-height` here, filtering
   down to a handful of cards would shrink the dialog and drag the search box and chips up
   the screen with it - jarring on every keystroke and every chip click. Fixed height means
   only `.library-body` below ever scrolls, and the chrome above it never moves. */
.library[b-jy5pt5yaa4] {
    width: min(72rem, 94vw);
    height: 86vh;
    padding: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--cf-border);
    border-radius: 10px;
    background: var(--cf-pane);
    color: var(--cf-text);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.875rem;
}

.library[b-jy5pt5yaa4]::backdrop {
    background: rgba(4, 7, 10, 0.62);
}

.library-head[b-jy5pt5yaa4] {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    flex: none;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--cf-border);
    background: var(--cf-pane-alt);
}

.library-title[b-jy5pt5yaa4] {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.library-sub[b-jy5pt5yaa4] {
    margin: 0 auto 0 0;
    color: var(--cf-muted);
    font-size: 0.75rem;
}

.library-close[b-jy5pt5yaa4] {
    display: grid;
    place-items: center;
    flex: none;
    width: 1.75rem;
    height: 1.75rem;
    border: 1px solid transparent;
    border-radius: 6px;
    background: none;
    color: var(--cf-muted);
    font: inherit;
    font-size: 0.8125rem;
    cursor: pointer;
}

.library-close:hover[b-jy5pt5yaa4] {
    border-color: var(--cf-border);
    background: var(--cf-chrome-hover);
    color: var(--cf-text);
}

.library-body[b-jy5pt5yaa4] {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding: 1rem;
}

.library-filters[b-jy5pt5yaa4] {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.library-search[b-jy5pt5yaa4] {
    flex: 1 1 14rem;
    min-width: 10rem;
    padding: 0.375rem 0.625rem;
    border: 1px solid var(--cf-border);
    border-radius: 6px;
    background: var(--cf-chrome-2);
    color: var(--cf-text);
    font: inherit;
    font-size: 0.8125rem;
}

.library-search:focus-visible[b-jy5pt5yaa4] {
    border-color: var(--cf-accent-dim);
    outline: none;
}

.library-chips[b-jy5pt5yaa4] {
    display: flex;
    gap: 0.375rem;
    flex-wrap: wrap;
}

.chip[b-jy5pt5yaa4] {
    padding: 0.1875rem 0.625rem;
    border: 1px solid var(--cf-border);
    border-radius: 999px;
    background: var(--cf-chrome-2);
    color: var(--cf-muted);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.chip:hover[b-jy5pt5yaa4] {
    background: var(--cf-chrome-hover);
    color: var(--cf-text);
}

.chip.is-on[b-jy5pt5yaa4] {
    border-color: var(--cf-accent-dim);
    background: var(--cf-accent-wash);
    color: var(--cf-accent);
}

.library-empty[b-jy5pt5yaa4] {
    margin: 2rem 0;
    color: var(--cf-muted);
    font-size: 0.8125rem;
    text-align: center;
}

/* Columns rather than a grid: cards differ in height by a line or two, and a grid leaves
   its short rows trailing space where a column flow simply packs the next card in. */
.library-cards[b-jy5pt5yaa4] {
    columns: 21rem;
    column-gap: 1rem;
}

.library-card[b-jy5pt5yaa4] {
    break-inside: avoid;
    margin-bottom: 1rem;
    padding: 0.6875rem 0.8125rem;
    border: 1px solid var(--cf-border-soft);
    border-radius: 8px;
    background: var(--cf-pane-alt);
}

.library-card-head[b-jy5pt5yaa4] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.4375rem;
}

.library-card-head h3[b-jy5pt5yaa4] {
    margin: 0;
    color: var(--cf-text);
    font-size: 0.8125rem;
    font-weight: 600;
}

.library-category[b-jy5pt5yaa4] {
    flex: none;
    color: var(--cf-faint);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* The expression itself, each field in its own hue - the same ones the strip and the grids
   use, so a card is already saying which position is which. Laid out as a flex row because
   the fields are separate elements and the gap is what puts the spaces back between them. */
.library-expression[b-jy5pt5yaa4] {
    display: flex;
    gap: 0 0.6ch;
    flex-wrap: wrap;
    margin: 0 0 0.4375rem;
    padding: 0.3125rem 0.4375rem;
    border-radius: 5px;
    background: var(--cf-chrome-2);
    font-size: 0.875rem;
    font-weight: 600;
}

.library-says[b-jy5pt5yaa4] {
    margin: 0 0 0.3125rem;
    color: var(--cf-text);
    font-size: 0.8125rem;
    line-height: 1.4;
}

.library-desc[b-jy5pt5yaa4] {
    margin: 0;
    color: var(--cf-muted);
    font-size: 0.75rem;
    line-height: 1.45;
}

.library-card-actions[b-jy5pt5yaa4] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.625rem;
}

.library-next[b-jy5pt5yaa4] {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    color: var(--cf-faint);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.library-use[b-jy5pt5yaa4] {
    flex: none;
    padding: 0.25rem 0.6875rem;
    border: 1px solid var(--cf-accent-dim);
    border-radius: 6px;
    background: var(--cf-accent-wash);
    color: var(--cf-accent);
    font: inherit;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
}

.library-use:hover[b-jy5pt5yaa4] {
    background: var(--cf-accent);
    color: var(--cf-accent-ink);
}

@media (max-width: 57.59rem) {
    .library[b-jy5pt5yaa4] {
        width: 96vw;
        height: 92vh;
    }

    .library-body[b-jy5pt5yaa4] {
        padding: 0.75rem;
    }

    .library-sub[b-jy5pt5yaa4] {
        display: none;
    }
}
/* /Components/NextRuns.razor.rz.scp.css */
/* The times, in reading order: left to right, then down. A grid rather than a wrapping flex
   row so that the dates and clocks line up in columns down the band, which is what lets the
   eye run down one column as easily as across a row.

   `align-content: start` keeps a short list at the top of the band rather than spread down
   it, so ten runs look like ten runs rather than like a sparse hundred. */
.runs[b-obv0z2ch7t] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    align-content: start;
    gap: 0.125rem 0.75rem;
    padding: 0.5rem 0.75rem 0.75rem;
}

.run[b-obv0z2ch7t] {
    display: flex;
    align-items: baseline;
    gap: 0.4375rem;
    min-width: 0;
    padding: 0.125rem 0.25rem;
    border-radius: 4px;
}

/* The date, on every entry, because nothing here may depend on what it wrapped next to.
   Faint by default so that a hundred of them read as a background against which the clock
   readings stand out. */
.run-date[b-obv0z2ch7t] {
    flex: none;
    color: var(--cf-faint);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The first entry of a day, in full. This is what makes day boundaries visible - a bright
   date among dim ones - and it costs no element that could be orphaned by a wrap. A schedule
   that fires once a day lights every entry, which is exactly right for one. */
.run.is-day .run-date[b-obv0z2ch7t] {
    color: var(--cf-muted);
    font-weight: 600;
}

.run-clock[b-obv0z2ch7t] {
    flex: none;
    color: var(--cf-text);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* How far off, in the short form - the long one would ellipsise here on most entries. It is
   the last thing to go when the column is narrow. */
.run-away[b-obv0z2ch7t] {
    min-width: 0;
    overflow: hidden;
    color: var(--cf-faint);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The one that is about to happen. It is the answer to the question most people opened the
   page with, so it is the one entry that is not the same weight as the rest. */
.run.is-next[b-obv0z2ch7t] {
    background: var(--cf-accent-wash);
}

.run.is-next .run-date[b-obv0z2ch7t] {
    color: var(--cf-accent);
    font-weight: 600;
}

.run.is-next .run-clock[b-obv0z2ch7t] {
    color: var(--cf-accent);
    font-weight: 700;
}

.run.is-next .run-away[b-obv0z2ch7t] {
    color: var(--cf-text);
}

.runs-none[b-obv0z2ch7t] {
    margin: 0;
    padding: 0.625rem 0.75rem;
    color: var(--cf-muted);
    font-size: 0.75rem;
    line-height: 1.5;
}
/* /Components/ThemeToggle.razor.rz.scp.css */
.theme-btn[b-wg0virrdny] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--cf-border);
    border-radius: 999px;
    background: transparent;
    color: var(--cf-muted);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.theme-btn:hover:not(:disabled)[b-wg0virrdny] {
    background: var(--cf-chrome-hover);
    color: var(--cf-text);
}

.theme-btn:disabled[b-wg0virrdny] {
    cursor: default;
    opacity: 0.6;
}

/* The label is the first thing to go when the chrome tightens - the glyph on its
   own still says which way the switch will move. */
@media (max-width: 1228.78px) {
    .theme-btn-label[b-wg0virrdny] {
        display: none;
    }
}
/* /Layout/ShellLayout.razor.rz.scp.css */
/* Fixed to the viewport, so the panes divide a known height between them and the
   page itself never scrolls: every pane that can overflow scrolls inside its own
   box, which is what keeps the expression, its grids and its next runs all on
   screen at once. */
.cf-shell[b-ufwt5007kf] {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--cf-bg);
    color: var(--cf-text);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.875rem;
}

/* On a narrow screen the fixed shell is given up. The expression band, six grids and a
   list of fire times inside one viewport height would leave every one of them too short
   to read - so the page scrolls instead, and each pane is as tall as it needs to be. */
@media (max-width: 57.59rem) {
    .cf-shell[b-ufwt5007kf] {
        position: static;
        min-height: 100dvh;
        overflow: visible;
    }
}
/* /Pages/NotFound.razor.rz.scp.css */
/* Centred in what is left of the shell below the app bar. */
.missing[b-j8zrbnqsyn] {
    flex: 1;
    display: grid;
    place-items: center;
    padding: 2rem;
    text-align: center;
}

.missing h1[b-j8zrbnqsyn] {
    margin: 0 0 0.5rem;
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.missing p[b-j8zrbnqsyn] {
    margin: 0 0 1rem;
    color: var(--cf-muted);
}

.missing a[b-j8zrbnqsyn] {
    color: var(--cf-accent);
    font-size: 0.875rem;
}
/* /Pages/Workbench.razor.rz.scp.css */
/* ── The expression band ──────────────────────────────────────────────────────
   Full width and at the top, because it is what the page is about. Everything
   below is a reading of it, and both readings want width more than this does. */
.cf-top[b-lcu24cydia] {
    flex: none;
    --pane-hue: var(--cf-accent);
    border-bottom: 1px solid var(--cf-border);
}

.cf-band[b-lcu24cydia] {
    padding: 0.75rem 1rem 0.75rem;
}

/* Everything the app has to say about the boxes above, in a patch of the band that is
   always exactly this tall.

   The height is the point of it. The sentence rewords itself, and findings appear and
   disappear as the expression changes - turning seconds on adds one - so sizing this to
   its contents moved the presets underneath it and the grids under those, out from under
   a reader who was aiming at them. Four and a half lines covers the sentence and a
   finding or two; more than that scrolls, which is a scrollbar in one small box rather
   than the whole page shifting. */
.cf-read[b-lcu24cydia] {
    box-sizing: border-box;
    height: 4.5rem;
    overflow-y: auto;
    margin-top: 0.75rem;
    padding: 0.4375rem 0.5625rem;
    border: 1px solid var(--cf-border-soft);
    border-radius: 6px;
    background: var(--cf-pane-alt);
}

.cf-said[b-lcu24cydia] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* The sentence. The largest text on the page after the expression itself. */
.cf-says[b-lcu24cydia] {
    margin: 0;
    color: var(--cf-text);
    font-size: 1.0625rem;
    line-height: 1.4;
}

.cf-said-spacer[b-lcu24cydia] {
    flex: 1;
    min-width: 0;
}

.finds[b-lcu24cydia] {
    margin: 0.375rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.75rem;
}

/* A clean expression has nothing to report, and an empty list should not push a gap. */
.finds:empty[b-lcu24cydia] {
    margin: 0;
}

.find[b-lcu24cydia] {
    display: flex;
    align-items: baseline;
    gap: 0.4375rem;
    padding: 0.125rem 0;
    color: var(--cf-muted);
    line-height: 1.45;
}

/* The mark is a fixed width so the sentences line up down the left however many
   findings there are and whatever mix of marks they carry. */
.find-mark[b-lcu24cydia] {
    flex: none;
    width: 0.75rem;
    color: var(--tone, var(--cf-faint));
    font-weight: 700;
    text-align: center;
}

.find-bad[b-lcu24cydia] {
    --tone: var(--cf-danger);
    color: var(--cf-text);
}

.find-warn[b-lcu24cydia] {
    --tone: var(--cf-warn);
    color: var(--cf-text);
}

.find-note[b-lcu24cydia] {
    --tone: var(--cf-faint);
}

/* Always on the page rather than only on an empty one. There is no empty state any
   more - the strip always holds five boxes - and a preset is the fastest way to get
   near what you want before dragging the grids to the rest of it. */
.cf-presets[b-lcu24cydia] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}

.cf-presets-label[b-lcu24cydia] {
    flex: none;
    margin-right: 0.125rem;
    color: var(--cf-faint);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ── The two readings ─────────────────────────────────────────────────────────
   Stacked, so the page reads as three bands: the expression, what it matches, and
   when that comes to. Both readings then have the full width, which each of them
   uses - the grids to sit side by side rather than in a column, and the times to
   run across rather than down.

   The sizing below is what removes the blank slab this pane used to end with. The
   grids take exactly the height they need; the times take everything else. Surplus
   height on a tall window therefore turns into more fire times on screen instead of
   into nothing at all. */
.cf[b-lcu24cydia] {
    position: relative;
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    background: var(--cf-bg);
}

/* `0 1 auto` - the height of its grids, and no more.

   Both bounds are load-bearing. `.pane` sets `overflow: hidden`, which zeroes a flex
   item's automatic minimum size, so without a floor this band would happily shrink to
   nothing. And the ceiling is what keeps the promise the other way round: on a window
   too narrow to fit the grids on one line they take two, and without it that would
   crowd the times back out of the page. Past 60% the grids scroll instead. */
.cf-fields[b-lcu24cydia] {
    flex: 0 1 auto;
    min-height: 9rem;
    max-height: 60%;
    --pane-hue: var(--cf-accent);
}

/* The grids flow into as many columns as the pane is wide enough for, so a wide
   window shows all six at once rather than a tall single column with four of them
   below the fold. Seventeen rem is where a ten-column minute grid still has room for
   two digits in a cell, and it is deliberately narrow enough that an ordinary laptop
   with the fixed next-runs column beside it still gets two columns of grids. */
/* `flex-basis: auto` rather than the usual `flex: 1`, so that the band above can take its
   height from what is actually in here. `min-height: 0` is what lets it scroll once the
   ceiling above bites.

   Fifteen rem is the widest a track can be while still fitting all five grids on one line
   on an ordinary 1920 display - at seventeen it was four, and the fifth wrapped onto a
   second line that the band then had to be tall enough to hold.

   `auto-fit` rather than `auto-fill`, and the difference is the whole of why the grids now
   reach the right-hand edge. Both work out how many tracks of that width would fit; the
   difference is what happens to the ones nothing lands in. `auto-fill` keeps them, so five
   grids in a row with space for six sat over on the left with an empty track beside them.
   `auto-fit` collapses the empty ones, and the `1fr` on the rest then shares the whole
   width out between the grids that exist. */
.cf-fields-body[b-lcu24cydia] {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    align-content: start;

    /* Each grid ends where its own cells do. Without this they are stretched to the
       tallest in the row, which puts a slab of nothing inside the short ones - and
       with all six on one line, the shortest is a single row of weekdays beside six
       rows of minutes. */
    align-items: start;
}

/* `1 1 0` - no base size of its own, so it takes whatever the grids leave. The floor
   keeps it worth looking at when the grids are tall enough to crowd it. */
.cf-runs[b-lcu24cydia] {
    flex: 1 1 0;
    min-height: 8rem;
    --pane-hue: var(--cf-accent);
    border-top: 1px solid var(--cf-border);
}

.cf-runs-body[b-lcu24cydia] {
    flex: 1;
    min-height: 0;
    overflow: auto;
}

/* ── Status bar ───────────────────────────────────────────────────────────────── */

.statusbar[b-lcu24cydia] {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex: none;
    padding: 0.25rem 0.75rem;
    background: var(--cf-chrome);
    border-top: 1px solid var(--cf-border);
    color: var(--cf-muted);
    font-size: 0.6875rem;
}

.statusbar-item[b-lcu24cydia] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.statusbar-spacer[b-lcu24cydia] {
    flex: 1;
}

.statusbar-note[b-lcu24cydia] {
    min-width: 0;
    overflow: hidden;
    color: var(--cf-faint);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Something the user asked for did not happen. Muted rather than red: nothing on screen
   is wrong, there is just another way to get at it. */
.statusbar-warn[b-lcu24cydia] {
    min-width: 0;
    overflow: hidden;
    color: var(--cf-text);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Narrow screens ───────────────────────────────────────────────────────────── */

@media (max-width: 76.79rem) {
    .statusbar-note[b-lcu24cydia] {
        display: none;
    }
}

/* Below tablet width the page scrolls rather than the panes: nothing divides a fixed
   height any more, so every band is as tall as what is in it. The bands are already
   stacked at every width, so only the sizing changes here. */
@media (max-width: 57.59rem) {
    .cf-fields[b-lcu24cydia],
    .cf-fields-body[b-lcu24cydia],
    .cf-runs[b-lcu24cydia],
    .cf-runs-body[b-lcu24cydia] {
        flex: none;
        min-height: 0;
        overflow: visible;
    }

    /* The ceiling exists to stop the grids crowding out the times when they are dividing
       one screen between them. Here they are not - the page scrolls - so it would only
       clip them. */
    .cf-fields[b-lcu24cydia] {
        max-height: none;
    }

    .cf-presets[b-lcu24cydia] {
        /* One line that scrolls sideways, rather than four lines of chips pushing the
           grids off the first screen. */
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 0.25rem;
    }

    /* The page itself scrolls here, and a small box that scrolls inside a page that
       scrolls is worse to use than one that grows - especially under a thumb. It keeps
       its floor, so the common case of a finding appearing still moves nothing. */
    .cf-read[b-lcu24cydia] {
        height: auto;
        min-height: 4.5rem;
        overflow-y: visible;
    }
}
