/* /Components/DiffView.razor.rz.scp.css */
/* Scoped to DiffView.
 *
 * Everything that describes what a diff LOOKS like now lives in wwwroot/css/app.css
 * under DIFF, on design tokens (.diff-file, .diff-file__header, .diff, .diff-num,
 * .diff-marker, .diff-code, .diff-hunk, .diff-stat, .diff-truncated). It was written
 * there by #139 as a shared contract, which is what makes the diff theme with the rest
 * of the app and have a dark mode at all — this file previously hard-coded GitHub's
 * light-mode hexes (#e6ffec, #fff, #f6f8fa), so under a dark theme it produced pale
 * green panels with near-invisible text, and none of it responded to the
 * colour-vision palette switch.
 *
 * What is left here is only what a global contract cannot know: that this component's
 * file header is a <button> rather than a <div>, plus the small labels beside it.
 * Every value is a token, so this file cannot drift from the theme either.
 */

/* The header is the disclosure control, so it has to be a real button — but a button's
 * UA styling (centred text, its own font, a border) fights the .diff-file__header
 * layout it is sharing. These reset that without touching colour, which the shared
 * rule owns. */
.diff-file__toggle[b-42x7ppyls6] {
    inline-size: 100%;
    border: 0;
    border-block-end: 1px solid var(--border-default);
    font: inherit;
    color: inherit;
    text-align: start;
    cursor: pointer;
    /* Not space-between: caret, path and change-kind belong together on the left, and
       the +/− counts are pushed right by .diff-stat's auto margin below. */
    justify-content: flex-start;
}

.diff-file__toggle:hover[b-42x7ppyls6] {
    background-color: var(--bg-inset);
}

/* Focus is never removed, only restyled. Inset, because the button spans the panel's
   full width and an outset ring would be clipped by .diff-file's overflow: hidden — a
   focus indicator present in the CSSOM but invisible on screen is the same failure as
   not having one. */
.diff-file__toggle:focus-visible[b-42x7ppyls6] {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: calc(-1 * var(--focus-ring-width));
}

.diff-caret[b-42x7ppyls6] {
    flex: none;
    inline-size: 0.75rem;
    color: var(--fg-muted);
}

/* min-inline-size: 0 so .trunc-start can actually shrink; a flex item defaults to
   min-content and would otherwise push the counts off the panel instead of eliding. */
.diff-path[b-42x7ppyls6] {
    min-inline-size: 0;
    font-family: var(--font-mono);
    font-size: var(--text-2);
    color: var(--fg-default);
}

/* "modified", "renamed", "binary" — a word, not an icon and not a colour, so it needs
   no legend and survives every palette axis. */
.diff-kind[b-42x7ppyls6] {
    flex: none;
    color: var(--fg-muted);
    font-size: var(--text-1);
    text-transform: lowercase;
}

.diff-file__toggle .diff-stat[b-42x7ppyls6] {
    margin-inline-start: auto;
}

/* The binary-file note. Deliberately not .diff-truncated: nothing is missing here, the
   file simply has no textual diff, so it must not borrow the attention styling that
   means "you have not seen everything". */
.diff-note[b-42x7ppyls6] {
    margin: 0;
    padding: var(--space-2) var(--space-3);
    background-color: var(--bg-muted);
    color: var(--fg-muted);
    font-size: var(--text-1);
}

/* ===========================================================================
   REVIEW CONVERSATION (#19)
   Scoped here rather than added to app.css: this is one component's layout, not
   a shared contract, and app.css is being pruned on another branch. Every value
   is a token, so it themes and gets dark mode like everything else.
   =========================================================================== */

/* Thread count on a COLLAPSED file header. Deliberately a number plus a
   visually-hidden word plus an aria-hidden glyph — the glyph alone would be a
   picture with no accessible name, and the colour alone would say nothing at
   all. */
.diff-threads[b-42x7ppyls6] {
    flex: none;
    display: inline-flex;
    gap: var(--space-1);
    align-items: baseline;
    padding: 0.1em 0.5em;
    border: 1px solid var(--border-accent);
    border-radius: var(--radius-pill);
    background-color: var(--bg-accent-muted);
    color: var(--fg-accent);
    font-size: var(--text-0);
    font-weight: var(--weight-semibold);
}

.review-block[b-42x7ppyls6] {
    margin-block: var(--space-3);
    padding-inline: var(--space-3);
}

.review-block__title[b-42x7ppyls6] {
    margin: 0 0 var(--space-1);
    font-size: var(--text-2);
    font-weight: var(--weight-semibold);
    color: var(--fg-default);
}

.review-block__lead[b-42x7ppyls6] {
    margin: 0 0 var(--space-2);
    font-size: var(--text-1);
    color: var(--fg-muted);
}

.review-notes[b-42x7ppyls6] {
    margin: 0 0 var(--space-2);
    padding-inline-start: var(--space-4);
    font-size: var(--text-1);
}

.review-empty[b-42x7ppyls6] {
    margin: var(--space-2) var(--space-3);
    font-size: var(--text-1);
    color: var(--fg-muted);
}

.review-list[b-42x7ppyls6] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.review-entry + .review-entry[b-42x7ppyls6] {
    margin-block-start: var(--space-2);
    padding-block-start: var(--space-2);
    border-block-start: 1px solid var(--border-muted);
}

.review-entry__head[b-42x7ppyls6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: baseline;
    margin: 0;
    font-size: var(--text-1);
}

.review-entry__who[b-42x7ppyls6] {
    font-weight: var(--weight-semibold);
    color: var(--fg-default);
}

.review-entry__when[b-42x7ppyls6],
.review-entry__link[b-42x7ppyls6] {
    color: var(--fg-muted);
}

/* white-space: pre-wrap, and this is load-bearing rather than cosmetic. The body
   is rendered as TEXT (never MarkupString — see #168 H2), so the author's own
   line breaks are the only structure it has left; collapsing them would turn a
   numbered list of objections into a single paragraph. overflow-wrap keeps a
   pasted URL or stack frame from widening the panel. */
.review-entry__body[b-42x7ppyls6] {
    margin: var(--space-1) 0 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: var(--text-1);
    color: var(--fg-default);
}

/* A thread inside the diff table, spanning all four columns so it sits directly
   under the line it is about. A row rather than an overlay or a sibling list:
   the browser keeps it with its line through every reflow, and it stays in
   reading order for a screen reader working down the table. */
.diff-thread-cell[b-42x7ppyls6] {
    padding: var(--space-2) var(--space-3);
    /* The diff's own left rail is line numbers; indenting the thread past it is
       what makes "this belongs to the line above" readable rather than looking
       like another line of code. */
    padding-inline-start: var(--space-5);
    background-color: var(--bg-muted);
    border-block: 1px solid var(--border-muted);
    /* The table cell inherits the diff's monospace and nowrap; a conversation is
       prose and must wrap. */
    white-space: normal;
    font-family: var(--font-sans);
}

/* The per-line comment affordance. A cell of its own so it can never overlap
   the code or shift it, and narrow enough that it costs the code column almost
   nothing. */
.diff-act[b-42x7ppyls6] {
    inline-size: 1.75rem;
    padding: 0;
    text-align: center;
    vertical-align: top;
}

/* Always rendered, never hover-only: hover is not something a keyboard has, and
   a control that only exists on hover is a control a screen-reader user cannot
   find. Low contrast at rest so 1,500 of them do not shout, full contrast on
   hover and on focus. The focus ring is never removed. */
.diff-comment[b-42x7ppyls6] {
    inline-size: 1.25rem;
    block-size: 1.25rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--fg-subtle);
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

.diff-comment:hover[b-42x7ppyls6] {
    background-color: var(--bg-accent-emphasis);
    color: var(--fg-on-emphasis);
}

.diff-comment:focus-visible[b-42x7ppyls6] {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: 1px;
    color: var(--fg-accent);
}

.compose[b-42x7ppyls6] {
    max-inline-size: 48rem;
}

.compose__actions[b-42x7ppyls6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-block-start: var(--space-2);
}

/* The queue of line comments held for the next submission. Visible and
   itemised, because a queue you cannot see is a queue that posts something you
   had changed your mind about. */
.pending[b-42x7ppyls6] {
    margin-block-end: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-accent);
    border-radius: var(--radius-md);
    background-color: var(--bg-accent-muted);
}

.pending__title[b-42x7ppyls6] {
    margin: 0 0 var(--space-1);
    font-size: var(--text-1);
    font-weight: var(--weight-semibold);
    color: var(--fg-accent);
}

.pending__list[b-42x7ppyls6] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.pending__item[b-42x7ppyls6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: baseline;
    font-size: var(--text-1);
}

.pending__line[b-42x7ppyls6] {
    flex: none;
    color: var(--fg-muted);
}

.pending__note[b-42x7ppyls6] {
    margin: var(--space-1) 0 0;
    font-size: var(--text-0);
    color: var(--fg-muted);
}
/* /Components/ReviewThreadPanel.razor.rz.scp.css */
/* Scoped to ReviewThreadPanel (#19).
 *
 * Here rather than in app.css for the reason DiffView's stylesheet gives: this is
 * one component's internal layout, not a shared visual contract, and app.css is
 * being pruned on another branch. Every value is a design token, so this cannot
 * drift from the theme and gets light/dark for free.
 *
 * What this file must NOT do: carry meaning in colour alone. Resolved, open and
 * outdated are .status pills from app.css, which pair every value with a glyph.
 * The rules here only adjust emphasis.
 */

.thread[b-js4gy0myyi] {
    padding: var(--space-2);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    background-color: var(--bg-surface);
    font-family: var(--font-sans);
    /* Prose, inside a table that is otherwise nowrap monospace. */
    white-space: normal;
}

.thread + .thread[b-js4gy0myyi] {
    margin-block-start: var(--space-2);
}

/* Resolved threads are de-emphasised, never hidden and never colour-only: the
   "resolved" pill above carries the state with a glyph, and this is the visual
   echo of it. A settled argument should not compete for attention with an open
   one — but a reviewer must still be able to read why it was settled, so nothing
   here reduces contrast on the text itself. */
.thread--resolved[b-js4gy0myyi] {
    background-color: var(--bg-muted);
    border-style: dashed;
}

.thread__head[b-js4gy0myyi] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: baseline;
    margin-block-end: var(--space-1);
}

.thread__where[b-js4gy0myyi] {
    min-inline-size: 0;
    font-size: var(--text-1);
    color: var(--fg-muted);
}

.thread__empty[b-js4gy0myyi] {
    margin: 0;
    font-size: var(--text-1);
    color: var(--fg-muted);
}

.thread__comments[b-js4gy0myyi] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.thread__comment + .thread__comment[b-js4gy0myyi] {
    margin-block-start: var(--space-2);
    padding-block-start: var(--space-2);
    border-block-start: 1px solid var(--border-muted);
}

.thread__byline[b-js4gy0myyi] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: baseline;
    margin: 0;
    font-size: var(--text-1);
}

.thread__who[b-js4gy0myyi] {
    font-weight: var(--weight-semibold);
    color: var(--fg-default);
}

.thread__when[b-js4gy0myyi],
.thread__link[b-js4gy0myyi] {
    color: var(--fg-muted);
}

/* pre-wrap is load-bearing, not styling. The body is rendered as TEXT and never
   as markup (#168 H2), so the author's own newlines are the only structure it
   has; collapsing them turns a numbered list of objections into one paragraph.
   overflow-wrap stops a pasted URL or stack frame from widening the diff table
   it is sitting inside. */
.thread__body[b-js4gy0myyi] {
    margin: var(--space-1) 0 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: var(--text-2);
    color: var(--fg-default);
}

.thread__reply[b-js4gy0myyi] {
    margin-block-start: var(--space-2);
    padding-block-start: var(--space-2);
    border-block-start: 1px solid var(--border-muted);
}

.thread__actions[b-js4gy0myyi] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-block-start: var(--space-2);
}
/* /Components/ThemePreview.razor.rz.scp.css */
/* Scoped to ThemePreview.
 *
 * Every value here is a design token, without exception. That is not tidiness — this component's
 * entire job is to show what the tokens resolve to, so a hard-coded colour anywhere in it would be
 * a lie about the theme being previewed. If something in here cannot be expressed with a token,
 * the token surface is missing something and that is the bug to fix.
 *
 * The frame itself carries the theme (an attribute for a built-in palette, custom properties set
 * through the CSSOM for an imported one) and everything inside inherits from it. Which is why this
 * file styles layout and nothing else.
 */

.theme-preview[b-6ebulcn9d9] {
    margin: 0;
}

.theme-preview__frame[b-6ebulcn9d9] {
    /* The token values land here, so this is the boundary of the previewed theme. */
    background-color: var(--bg-canvas);
    color: var(--fg-default);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* tokens.css expresses the whole light/dark axis with light-dark(), which resolves against the
   element it is USED on — so declaring a colour-scheme here is the entire implementation of
   "preview the default palette in the other mode". No JavaScript and no second set of values. */
.theme-preview__frame--light[b-6ebulcn9d9] {
    color-scheme: light;
}

.theme-preview__frame--dark[b-6ebulcn9d9] {
    color-scheme: dark;
}

/* --- compact: a colour strip for a row in a list of options ------------------------------ */

.theme-preview--compact .theme-preview__frame[b-6ebulcn9d9] {
    display: flex;
    inline-size: 5.5rem;
    block-size: 1.25rem;
    border-radius: var(--radius-sm);
}

.theme-preview__chip[b-6ebulcn9d9] {
    flex: 1 1 auto;
}

.theme-preview__chip--canvas[b-6ebulcn9d9]  { background-color: var(--bg-canvas); }
.theme-preview__chip--surface[b-6ebulcn9d9] { background-color: var(--bg-muted); }
.theme-preview__chip--accent[b-6ebulcn9d9]  { background-color: var(--bg-accent-emphasis); }
.theme-preview__chip--success[b-6ebulcn9d9] { background-color: var(--diff-addition-word-bg); }
.theme-preview__chip--danger[b-6ebulcn9d9]  { background-color: var(--diff-deletion-word-bg); }
.theme-preview__chip--text[b-6ebulcn9d9]    { background-color: var(--fg-default); }

/* --- full: a slice of the real application ----------------------------------------------- */

.theme-preview__body[b-6ebulcn9d9] {
    display: grid;
    gap: var(--space-2);
    padding: var(--space-3);
}

.theme-preview__heading[b-6ebulcn9d9] {
    margin: 0;
    font-size: var(--text-4);
    font-weight: var(--weight-semibold);
    color: var(--fg-default);
}

.theme-preview__text[b-6ebulcn9d9] {
    margin: 0;
    font-size: var(--text-2);
    color: var(--fg-muted);
}

.theme-preview__link[b-6ebulcn9d9] {
    color: var(--fg-link);
    text-decoration: underline;
}

.theme-preview__controls[b-6ebulcn9d9] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0;
}

/* Spans, not buttons: a preview must not put a dozen fake controls into the tab order or announce
   them as things that can be pressed. They only have to LOOK like the real thing. */
.theme-preview__btn[b-6ebulcn9d9] {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--space-3);
    block-size: var(--control-height-sm);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    background-color: var(--bg-surface);
    color: var(--fg-default);
    font-size: var(--text-1);
    font-weight: var(--weight-medium);
}

.theme-preview__btn--primary[b-6ebulcn9d9] {
    background-color: var(--bg-accent-emphasis);
    border-color: transparent;
    color: var(--fg-on-emphasis);
}

/* The focus ring, drawn statically. A theme that hides the focus indicator is unusable by
   keyboard, and "unusable by keyboard" is not something anyone should discover after applying it.
   Same width, colour and offset as the real ring in app.css, so what is shown is what happens. */
.theme-preview__btn--focused[b-6ebulcn9d9] {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: var(--focus-ring-offset);
}

/* Status pills keep their glyphs. Meaning never rests on colour alone anywhere in this product,
   and a preview that dropped the glyphs would suggest otherwise. */
.theme-preview__pill[b-6ebulcn9d9] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0 var(--space-2);
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    font-size: var(--text-0);
    font-weight: var(--weight-medium);
    line-height: 1.6;
}

.theme-preview__pill--success[b-6ebulcn9d9] {
    background-color: var(--bg-success-muted);
    border-color: var(--border-success);
    color: var(--fg-success);
}

.theme-preview__pill--danger[b-6ebulcn9d9] {
    background-color: var(--bg-danger-muted);
    border-color: var(--border-danger);
    color: var(--fg-danger);
}

.theme-preview__pill--attention[b-6ebulcn9d9] {
    background-color: var(--bg-attention-muted);
    border-color: var(--border-attention);
    color: var(--fg-attention);
}

.theme-preview__pill--done[b-6ebulcn9d9] {
    background-color: var(--bg-done-muted);
    border-color: var(--border-done);
    color: var(--fg-done);
}

/* The diff borrows app.css's own .diff rules for colour; only the framing is local. This is the
   part of the preview that matters most — the app is for reading diffs, so add/remove contrast is
   the thing worth judging a theme on. */
.theme-preview__diff[b-6ebulcn9d9] {
    margin: 0;
    border: 1px solid var(--border-muted);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
/* /Layout/ThemeToggle.razor.rz.scp.css */
/* Scoped to ThemeToggle.
 *
 * The three-state radio group itself is styled in app.css under `.theme-toggle`, where it was
 * written as a shared contract. What is here is only the wrapper that puts the settings link
 * beside it — a layout decision belonging to this component, not a colour decision belonging to
 * the design system.
 */

.theme-control[b-5vg3874eeh] {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

/* Square, matching the toggle's own 1.5rem cells so the header row does not gain a taller item.
   The link's accessible name is sr-only text inside it; the gear is aria-hidden, because an icon
   is not a name. */
.theme-control__more[b-5vg3874eeh] {
    padding-inline: var(--space-2);
    min-block-size: var(--control-height-sm);
}
/* /Pages/About.razor.rz.scp.css */
/*
 * About's own layout. Everything colour- or component-shaped comes from app.css / tokens.css; this
 * file only holds the two things that are specific to a long-form explanatory page.
 */

/*
 * Running prose gets a measure. Without one, the paragraphs here stretch to the full width of a
 * wide monitor — around 200 characters a line, which is roughly twice the point at which the eye
 * starts losing its place returning to the left edge. The cards and callouts below deliberately
 * keep the full width, because they are scanned rather than read.
 */
.about > section > p[b-7rlmoxbofn],
.about > section > .prose[b-7rlmoxbofn] {
    max-inline-size: 68ch;
}

/*
 * `.steps` was built for the one-line onboarding checklist on the home page. Here each step is a
 * bold lead plus a paragraph, which needs the lead to sit on its own line and the paragraph to read
 * at body weight rather than inheriting the list's muted small treatment.
 *
 * See the comment in About.razor for why each <li> must wrap its content in exactly one element —
 * the grid places a second child into the 1.5rem counter column and prose collapses to one
 * character per line.
 */
.steps > li > div > strong[b-7rlmoxbofn] {
    display: block;
    color: var(--fg-default);
}

.steps > li > div > p[b-7rlmoxbofn] {
    max-inline-size: 68ch;
    margin-block-start: var(--space-1);
    color: var(--fg-muted);
}

/*
 * Term/definition pairs in the security section. `dt` carries the claim and `dd` the reasoning, so
 * the indent browsers apply by default works against them being read as one unit.
 */
.about dd[b-7rlmoxbofn] {
    margin-inline-start: 0;
    max-inline-size: 68ch;
}
/* /Pages/Appearance.razor.rz.scp.css */
/* Scoped to Appearance.
 *
 * Layout only. Every colour is a token, because this page has to be legible while somebody is in
 * the middle of previewing a theme that is not — the moment a value here were hard-coded, this
 * page would stop being an honest place to judge a theme from.
 */

/* --- a list of radio options, each with a name and an explanation -------------------------
 *
 * Real <input type="radio"> in a real <fieldset>, which is what gets grouping, arrow-key
 * navigation, single-selection semantics and "selected" announced — all correctly, and all for
 * free. A row of <button aria-pressed> would need every one of those written by hand and would
 * still announce worse. Same reasoning as the header's theme toggle.
 */
.option-set[b-mp6efmss19] {
    display: grid;
    gap: var(--space-1);
    padding: 0;
    margin: 0;
    border: 0;
}

.option[b-mp6efmss19] {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-2);
    border-radius: var(--radius-md);
}

.option:hover[b-mp6efmss19] {
    background-color: var(--bg-hover);
}

/* The whole row reacts to focus, because the 16px radio is not a big enough target for the
   indicator to be easy to find. The input keeps its own ring as well — this adds to it rather
   than replacing it, so the ring is never the thing that got removed. */
.option:has(:focus-visible)[b-mp6efmss19] {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: var(--focus-ring-offset);
}

.option:has(:checked)[b-mp6efmss19] {
    background-color: var(--bg-selected);
}

.option > input[b-mp6efmss19] {
    flex: none;
    /* Line the control up with the first line of its label rather than the centre of a
       two-line block. */
    margin-block-start: 0.15rem;
}

.option > label[b-mp6efmss19] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-3);
    cursor: pointer;
}

.option__name[b-mp6efmss19] {
    font-weight: var(--weight-semibold);
    font-size: var(--text-3);
    color: var(--fg-default);
}

/* flex-basis 100% so the explanation always drops onto its own line under the name, rather than
   competing with it for width when the row happens to be wide. */
.option__note[b-mp6efmss19] {
    flex: 1 0 100%;
    font-size: var(--text-1);
    font-weight: var(--weight-normal);
    color: var(--fg-muted);
}

/* --- picker beside its preview ------------------------------------------------------------
 *
 * Two columns where there is room, stacked where there is not. The preview is what the choice is
 * actually made from, so it gets the wider column.
 */
.theme-picker[b-mp6efmss19] {
    display: grid;
    gap: var(--space-4);
}

@media (min-width: 48rem) {
    .theme-picker[b-mp6efmss19] {
        grid-template-columns: minmax(16rem, 2fr) 3fr;
        align-items: start;
    }
}

.theme-picker__preview[b-mp6efmss19] {
    position: sticky;
    /* Clears the sticky header, so scrolling through a long option list keeps the preview in
       view instead of sliding under the banner. */
    inset-block-start: calc(var(--layout-header-height) + var(--space-3));
}

.theme-picker__preview > h3[b-mp6efmss19] {
    margin-block: 0 var(--space-2);
    color: var(--fg-muted);
    font-size: var(--text-1);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
/* /Pages/Compose.razor.rz.scp.css */
/*
 * Compose's two-pane layout (Option B).
 *
 * The page's problem was never the styling — it was that the batch you were assembling and the
 * branches you were assembling it from could not be on screen at the same time. Picking lived above
 * the fold, the message below it, the preview below that and the submit button below THAT, so the
 * only way to check what you had built was to scroll away from the thing building it.
 *
 * So the layout is the fix: a scrolling picker on the left, a column on the right that holds the
 * batch and never scrolls out of reach. Everything here exists to serve that split. Anything that
 * is not layout uses the shared vocabulary in app.css.
 */

.compose[b-uynryv2mfk] {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--space-4);
    align-items: start;
}

/*
 * Below this width two columns stop being two columns and start being two very narrow ones. Stack
 * instead, picker first: on a phone you scroll to the batch, which is the ordering the old page had
 * anyway, so the narrow case is no worse than today and the wide case is much better.
 */
@media (max-width: 62rem) {
    .compose[b-uynryv2mfk] {
        grid-template-columns: minmax(0, 1fr);
    }

    .compose__build[b-uynryv2mfk] {
        position: static;
    }
}

.compose__pick[b-uynryv2mfk],
.compose__build[b-uynryv2mfk] {
    min-inline-size: 0;
}

/*
 * The whole point of the right column. `top` clears the app header; `max-height` plus the scroll on
 * the batch card means a forty-branch batch cannot push the submit button off the bottom of the
 * viewport — which would reintroduce exactly the problem this layout removes.
 */
.compose__build[b-uynryv2mfk] {
    position: sticky;
    top: var(--space-4);
}

/* --- the picker ------------------------------------------------------- */

/*
 * A repo and its branches, as one visual object. On the old flat table the repo name was reprinted
 * on every row, so salesforce-gearset's four branches read as four unrelated repositories.
 */
.grp[b-uynryv2mfk] {
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.grp + .grp[b-uynryv2mfk],
.grp + .empties[b-uynryv2mfk] {
    margin-block-start: var(--space-2);
}

.grp__header[b-uynryv2mfk] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    padding: var(--space-2) var(--space-3);
    background-color: var(--bg-muted);
    border-block-end: 1px solid var(--border-muted);
}

.grp__count[b-uynryv2mfk] {
    margin-inline-start: auto;
    color: var(--fg-muted);
    font-size: var(--text-1);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.branch[b-uynryv2mfk] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    padding: var(--space-2) var(--space-3);
    background-color: var(--bg-surface);
    font-size: var(--text-2);
}

.branch + .branch[b-uynryv2mfk] {
    border-block-start: 1px solid var(--border-muted);
}

.branch:hover[b-uynryv2mfk] {
    background-color: var(--bg-hover);
}

.branch__name[b-uynryv2mfk] {
    min-inline-size: 0;
    overflow-wrap: anywhere;
}

.branch__meta[b-uynryv2mfk] {
    margin-inline-start: auto;
    display: flex;
    gap: var(--space-2);
    align-items: center;
    color: var(--fg-muted);
    font-size: var(--text-1);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/*
 * The repositories with no matching branch. Collapsed rather than dropped: "nothing matched here"
 * and "this repo was never checked" are different states, and the old page was right to insist on
 * the difference. It was wrong about the weight — 105 rows saying nothing, given the same
 * prominence as the 9 rows saying something.
 */
.empties > summary[b-uynryv2mfk] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    padding: var(--space-2) var(--space-3);
    border: 1px dashed var(--border-neutral);
    border-radius: var(--radius-md);
    background-color: var(--bg-muted);
    color: var(--fg-muted);
    font-size: var(--text-2);
    cursor: pointer;
}

.empties > summary:hover[b-uynryv2mfk] {
    color: var(--fg-default);
}

.empties[open] > summary[b-uynryv2mfk] {
    border-end-start-radius: 0;
    border-end-end-radius: 0;
    border-block-end-style: solid;
}

.empties__list[b-uynryv2mfk] {
    max-block-size: 11rem;
    overflow-y: auto;
    padding: var(--space-2) var(--space-3);
    border: 1px dashed var(--border-neutral);
    border-block-start: 0;
    border-end-start-radius: var(--radius-md);
    border-end-end-radius: var(--radius-md);
    color: var(--fg-muted);
    font-size: var(--text-1);
    columns: 16rem auto;
    column-gap: var(--space-4);
}

.empties__list > div[b-uynryv2mfk] {
    break-inside: avoid;
}

/* --- the batch -------------------------------------------------------- */

/*
 * Scrolls internally so the fields and the submit button below it stay put no matter how many
 * branches are selected.
 */
.picks[b-uynryv2mfk] {
    max-block-size: 24rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3);
}

.pick[b-uynryv2mfk] {
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-default);
    border-inline-start: 2px solid var(--border-accent);
    border-radius: var(--radius-md);
    background-color: var(--bg-inset);
}

.pick__header[b-uynryv2mfk] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
}

.pick__remove[b-uynryv2mfk] {
    margin-inline-start: auto;
    padding: 0 var(--space-1);
    border: 0;
    background: none;
    color: var(--fg-muted);
    font-size: var(--text-4);
    line-height: 1;
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.pick__remove:hover[b-uynryv2mfk] {
    color: var(--fg-danger);
}

/*
 * Source and target on one line, both visible before you commit. On the old page the target was a
 * text input that only appeared AFTER ticking, in a table cell — so the question "what am I merging
 * this into" could not be answered at the moment you were deciding whether to include it.
 */
.pick__flow[b-uynryv2mfk] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    margin-block-start: var(--space-1);
    font-size: var(--text-1);
}

.pick__source[b-uynryv2mfk] {
    min-inline-size: 0;
    overflow-wrap: anywhere;
    color: var(--fg-muted);
}

.pick__arrow[b-uynryv2mfk] {
    color: var(--fg-accent);
    flex: none;
}

.pick__target[b-uynryv2mfk] {
    inline-size: 9rem;
    flex: none;
}

.pick__more[b-uynryv2mfk] {
    margin-block-start: var(--space-2);
    font-size: var(--text-1);
}

.pick__more > summary[b-uynryv2mfk] {
    color: var(--fg-muted);
    cursor: pointer;
}

.pick__more > summary:hover[b-uynryv2mfk] {
    color: var(--fg-default);
}

.pick__preview[b-uynryv2mfk] {
    max-block-size: 14rem;
    overflow: auto;
    margin: var(--space-2) 0 0;
    padding: var(--space-2);
    border: 1px solid var(--border-muted);
    border-radius: var(--radius-sm);
    background-color: var(--bg-canvas);
    font-size: var(--text-0);
    line-height: var(--leading-code);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.submit-row[b-uynryv2mfk] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    flex-wrap: wrap;
}
/* /Pages/Review.razor.rz.scp.css */
/* Scoped to Review (#19, #20).
 *
 * Here rather than in app.css, following DiffView's precedent: this is one page's
 * layout, not a shared visual contract — and app.css is being pruned on another
 * branch. Every value is a design token, so it themes and gets dark mode for free.
 *
 * Everything that carries MEANING on this page is an app.css .status pill, which
 * pairs each value with a glyph as well as a colour. Nothing in this file encodes
 * state; it only positions things.
 */

/* The reviewer's own marker: the pill for scanning eight rows at a glance, the
   select for changing one. Stacked rather than inline so the pill stays on the
   same reading line as the other status columns and the control sits under it,
   which keeps the row height uniform down the table. */
.mine[b-jfzv7qexfr] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    align-items: flex-start;
}

/* Wide enough for "Needs a comment" without truncating — a dropdown whose longest
   option is clipped is one where the reader cannot tell two states apart. */
.mine select[b-jfzv7qexfr] {
    inline-size: 100%;
    min-inline-size: 9rem;
}

.batch-verdicts[b-jfzv7qexfr] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-block: var(--space-3);
}
