/* @fileoverview The stylesheet's entry point: one partial per section, in cascade order. `npm run css` compiles
   it into public/css/app.css, which is committed; edit the partials, never the compiled file. */
/* @fileoverview Design tokens: the only place a raw size, color or duration is written. Every rule elsewhere uses
   these. They are the approved v0 design's (R100; design/v0-ui/REPORT.md in the planning repo, section 3.8), landed
   in the restyle's steps (REPORT 6.3). Two themes, each by day and at night: Slate, the default (Folio day, Paper
   night; step 2), and Violet (step 5), a person's own choice in Settings (Color; R82, R84), written as
   data-palette="violet" on the html element. Violet's blocks come after Slate's.

   Colors are roles, and dark mode redefines the roles and nothing else. Each theme's night roles come from one mixin,
   written twice, so the compiled app.css has two identical blocks for each theme, as test/css-theme.test.js wants.
   That test computes every pair in all four schemes: text and words on a color at least 4.5:1; a field's edge, the
   focus ring, the mark, a status's mark and the Coach's edge (its fill or its trim) at least 3:1 against the grounds
   they sit on.

   Which scheme a page gets: the account's setting puts data-theme="light" or "dark" on the html element
   (views/partials/top.ejs); with the setting at System there is no attribute and the device's own preference
   decides. Which theme: data-palette="violet" when the account chose Violet, and nothing for Slate. Dark and Violet
   are for the screen only, so anything printed, such as the interview brief, is dark ink on white paper whatever the
   theme or scheme. */
/* Slate at night: Paper night. */
/* Violet at night (REPORT 3.4). Its shadows are Slate's: Slate's night block, which matches the same page, gives them.
   The Coach's gold lip and trim and its white words are the same by day and at night (R82: "the same look in day and
   night"). */
:root {
  /* Spacing, on a 4px step. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  /* Type: four roles, so a component never names a face (REPORT 3.6). The faces come from npm with step 3 (R103);
     until then each role falls back to the system face after it. */
  --font-display: 'Lexend', system-ui, sans-serif; /* Titles, section heads, company names, the wordmark. */
  --weight-display: 300;
  --font-doc: 'Spectral', Georgia, serif; /* The resume paper, a letter. */
  --font-voice: 'Public Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; /* The Coach's words. */
  --font-accent: 'Spectral', Georgia, serif; /* The one decorative italic: a word in a title, the wordmark. */
  --font-sans: 'Public Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; /* Everything operated. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --text-xs: 0.75rem; /* 12px: labels in caps, counts. */
  --text-sm: 0.875rem; /* 14px: secondary lines, table cells on the Mac. */
  --text-base: 1rem; /* 16px: body, controls. */
  --text-md: 1.125rem; /* 18px: company names in lists. */
  --text-lg: 1.25rem; /* 20px: panel titles, phone company names (was 1.125rem). */
  --text-xl: 1.5rem; /* 24px: section heads. */
  --text-2xl: 2rem; /* 32px: phone page titles. */
  --text-3xl: 2.5rem; /* 40px: Mac page titles. */
  --leading-tight: 1.2;
  --leading: 1.55;
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-bold: 650;
  --tracking-caps: 0.08em;
  --measure: 68ch;
  --underline-offset: 0.18em; /* A link's underline, just clear of the descenders (REPORT 4.2.2; was 0.15em). */
  --underline-width: 1px; /* A link's underline at rest. */
  --underline-width-hover: 2px; /* The same, under the pointer. */
  --underline-offset-current: 0.3em;
  --page-width: 72rem;
  --field-min: 14rem;
  --field-narrow: 8rem;
  --cell-label: 7.5rem; /* The column of labels in a table collapsed to one block per row on a phone. */
  --self-view-width: 20rem; /* The practice session's picture of yourself (P3-07): small, as on a video call. */
  --self-view-ratio: 16 / 9; /* The camera's shape as asked for, 640x360. */
  /* Shape. */
  --radius-sm: 4px; /* The paper, a source tag, a file field's button. */
  --radius-md: 6px; /* Buttons and tags. Never a pill: round is for what is not pressed. */
  --radius-lg: 10px; /* Cards, rows, menus. */
  --radius-xl: 16px; /* Dialogs, sheets, a chat bubble. */
  --radius-pill: 999px; /* A status chip, the mock marker, a meter: things that are not pressed. */
  --radius-field: calc((var(--touch-min) + var(--space-2)) / 2); /* Every field you type in: 26px. */
  --radius-bubble: 1.25rem; /* The old chat bubble; goes with the conversation's restyle (step 15). */
  --border-width: 1px;
  --rule-width: 2px; /* The rule beside set-off words, such as a tighter version in a practice review (P3-04). */
  --button-edge: 1.5px; /* An outlined button's edge, in --accent (R81). */
  --current-mark: 3px; /* The --mark bar under the current place (R81). */
  --info-dot: 8px; /* The --mark dot before a current line (R81). */
  /* Motion. Every transition and animation stops under reduced motion (styles/_base.scss). */
  --dur-fast: 120ms; /* Hover and press. */
  --dur: 200ms; /* Opening. */
  --dur-turn: 800ms; /* A chevron turning; one turn of the old working mark. */
  --dur-working: 1600ms; /* One cycle of a working button's own icon (R77, R93). */
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --working-size: 1em; /* The old trailing working mark: goes with the buttons' restyle (step 8). */
  --working-width: 2px; /* The same. */
  /* Touch and focus. */
  --touch-min: 44px;
  --tag-height: 32px; /* A tag on the Mac as the board drew it; Q71, as suggested, keeps tags at 44px (step 17). */
  --focus-width: 3px;
  --focus-offset: 2px;
  --opacity-disabled: 0.6; /* The old disabled fade: goes with the buttons' restyle (step 8). */
  /* The parts' own sizes. */
  --rail-width: 232px;
  --rail-width-collapsed: 80px; /* Room for "Applications" at 12px under its icon. */
  --tabbar-height: 64px;
  --coach-button: 68px; /* The round Coach. */
  --coach-lip-size: 5px; /* The solid lip under it. */
  --coach-notch: 6px; /* The ring of page color round it. */
  --icon-size: 1.25em; /* An icon from the sprite beside its words: 20px in body text (REPORT 4.1.5). */
  --icon-sm: 16px; /* Beside small words: a back link, a link to more, a link out of the app (REPORT 3.9). */
  --icon-md: 20px; /* Icons in controls, rows and notices. */
  --icon-lg: 22px; /* Where a part says so (REPORT 3.9). */
  --swatch-width: 36px; /* The Color setting's swatch: a theme's page by day and at night, side by side (D10). */
  --swatch-height: 20px;
  --swatch-dot: 9px; /* The theme's Coach color on each half. */
  --status-height: 26px; /* A status chip, at least (REPORT 4.8.2). */
  --status-pad-block: 2px; /* Above and below its words. */
  --status-pad-start: 10px; /* Before its mark: a little less than after its words. */
  --status-dot: 9px; /* Its mark: a dot while in progress, a ring once closed. */
  --status-ring: 2px; /* A closed status's ring. */
  --status-dot-xs: 7px; /* What's new's 12px pill: its mark, */
  --status-pad-start-xs: 7px; /* and the room before it. */
  /* Stacking. */
  --z-header: 10; /* The old header: goes with the navigation (step 11); REPORT 3.9 has the new ladder. */
  --z-dialog: 100;
  --z-skip-link: 1000;
  /* Color roles, Slate by day: Folio day. Native controls (scroll bars, the file field's button, radio buttons)
     follow color-scheme. */
  color-scheme: light dark;
  --surface: #F7F8F6; /* The page. */
  --surface-raised: #FFFFFF; /* Cards, rows, fields, the resume paper, dialogs and sheets. */
  --surface-sunken: #ECEEEA; /* Wells; hover and pressed grounds; a disabled field; the switch's track. */
  --border: #D5D9D3; /* Hairlines and card edges: decoration, not a control's boundary. */
  --border-control: #7A827D; /* The edge of a field: 3:1 against the page. */
  --text: #1A2220;
  --text-muted: #535D59;
  --accent: #2F4256; /* The one filled main button per area; links; an outlined button's edge; checked controls. */
  --accent-strong: #22313F; /* Hover and press of the above. */
  --text-on-accent: #FFFFFF;
  --success: #2B6B36;
  --text-on-success: #FFFFFF;
  --danger: #B42318;
  --danger-strong: #861B12;
  --text-on-danger: #FFFFFF;
  --focus-ring: #2F4256;
  --accent-soft: #E6EAEF; /* A selected row or choice; a lit choice button. Never the current place. */
  --warning: #A84F0C; /* A line that needs fixing, always with the triangle. Never mock mode, due soon or advice. */
  --text-on-warning: #FFFFFF;
  --warning-soft: #FCEBE1; /* The ground of a warning notice. */
  --mark: #AD7D09; /* The theme's mark, in two places only: the current place's bar, the info dot (R81). */
  --scrim: rgb(14 20 19 / 0.45); /* Behind a dialog or a sheet. */
  --coach: #0F7A80; /* The Coach only: the round Coach, the Coach button, the Coach panel, its Send (R81, R96). */
  --coach-strong: #0B6166;
  --text-on-coach: #FFFFFF;
  --coach-lip: #0A4C51; /* The solid lip under the round Coach. */
  --coach-trim: transparent; /* A ring round the Coach: none by day, where its fill carries its edge. */
  --coach-glow: 0 0 0 3px rgb(15 122 128 / 0.2), 0 0 14px 2px rgb(15 122 128 / 0.4);
  --shadow-1: 0 1px 2px rgb(26 34 32 / 0.06); /* Cards, rows, the switch's chosen option. Shadows are colors too. */
  --shadow-2: 0 1px 2px rgb(26 34 32 / 0.05), 0 10px 28px rgb(26 34 32 / 0.09); /* The resume paper, the composer. */
  --shadow-3: 0 2px 6px rgb(26 34 32 / 0.08), 0 18px 48px rgb(26 34 32 / 0.16); /* Menus, dialogs and sheets. */
  /* The thirteen statuses (R45, R67; REPORT 3.5): a ground, a mark (a dot in progress, a ring once closed) and an
     ink, by the tokens' short keys; step 6 joins them to the app's own keys. */
  --status-drafting-bg: #E5E6E6;
  --status-drafting-mark: #797B7A;
  --status-drafting-ink: #5C5E5D;
  --status-applied-bg: #D0EAFE;
  --status-applied-mark: #0482C0;
  --status-applied-ink: #066494;
  --status-screen-bg: #D8E8FE;
  --status-screen-mark: #417ACC;
  --status-screen-ink: #245BAB;
  --status-assessment-bg: #E0E5FE;
  --status-assessment-mark: #686FCB;
  --status-assessment-ink: #4D51AA;
  --status-interviewing-bg: #E9E1FF;
  --status-interviewing-mark: #8565C1;
  --status-interviewing-ink: #6947A1;
  --status-final-bg: #FDD8FF;
  --status-final-mark: #A35AA7;
  --status-final-ink: #833C88;
  --status-offer-bg: #C3F6C3;
  --status-offer-mark: #3A8F42;
  --status-offer-ink: #157123;
  --status-accepted-bg: #B3F9D3;
  --status-accepted-mark: #06915F;
  --status-accepted-ink: #027048;
  --status-declined-bg: #FFDBEA;
  --status-declined-mark: #A66182;
  --status-declined-ink: #864565;
  --status-withdrawn-bg: #E5E6E6;
  --status-withdrawn-mark: #797B7A;
  --status-withdrawn-ink: #5C5E5D;
  --status-rejected-bg: #FEDDDA;
  --status-rejected-mark: #BF534E;
  --status-rejected-ink: #9D3533;
  --status-noresponse-bg: #E2EBCE;
  --status-noresponse-mark: #758055;
  --status-noresponse-ink: #596339;
  --status-jobclosed-bg: #F8E1D5;
  --status-jobclosed-mark: #937260;
  --status-jobclosed-ink: #755645;
  /* The Color setting's swatches (D10, R84): each theme's page with its Coach's color as the dot, by day and at night,
     the same whatever the theme and scheme on screen, so each choice is shown as it is. Each is its theme's --surface
     or --coach in that scheme, and test/css-theme.test.js holds it to that. */
  --swatch-slate-day: #F7F8F6;
  --swatch-slate-day-coach: #0F7A80;
  --swatch-slate-night: #1B1C18;
  --swatch-slate-night-coach: #2B776F;
  --swatch-violet-day: #F8F6FB;
  --swatch-violet-day-coach: #4A2BB5;
  --swatch-violet-night: #16131F;
  --swatch-violet-night-coach: #4B3A8F;
  /* Print (P3-01): black ink on white paper, whatever the theme or scheme on screen, so dark mode leaves these
     alone. */
  --print-text: 11pt;
  --print-ink: #000000;
  --print-paper: #ffffff;
}

/* Light, chosen on the account: native controls stay light too, whatever the device prefers. */
:root[data-theme=light] {
  color-scheme: light;
}

/* Slate at night: once for a device that prefers dark while the account says System, once for Dark chosen on the
   account. Screen only, so a printed page keeps the light roles. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    color-scheme: dark;
    --surface: #1B1C18;
    --surface-raised: #23241F;
    --surface-sunken: #141511;
    --border: #35362F;
    --border-control: #84867A;
    --text: #D9D4C6;
    --text-muted: #A7A396;
    --accent: #B3A991;
    --accent-strong: #C9C0A9;
    --text-on-accent: #1C1B16;
    --success: #A3D19B;
    --text-on-success: #10240D;
    --danger: #F4A097;
    --danger-strong: #F9C4BD;
    --text-on-danger: #3A0B06;
    --focus-ring: #B3A991;
    --accent-soft: #2D2D25;
    --warning: #F2A26A;
    --text-on-warning: #2A1405;
    --warning-soft: #2E2319;
    --mark: #D4A93C;
    --scrim: rgb(0 0 0 / 0.6);
    --coach: #2B776F;
    --coach-strong: #246F68;
    --text-on-coach: #F4F0E6;
    --coach-lip: #7CC2B6;
    /* A thin light teal ring, as Violet's gold trim, so the night Coach keeps a 3:1 edge on a raised card, where its
       fill is 2.96:1 (R104). The fill and its cream words stay. */
    --coach-trim: #7CC2B6;
    --coach-glow: 0 0 0 3px rgb(43 119 111 / 0.3), 0 0 16px 3px rgb(56 150 140 / 0.4);
    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.45);
    --shadow-2: 0 1px 2px rgb(0 0 0 / 0.4), 0 10px 28px rgb(0 0 0 / 0.45);
    --shadow-3: 0 2px 6px rgb(0 0 0 / 0.5), 0 18px 48px rgb(0 0 0 / 0.6);
    --status-drafting-bg: #2D2E2E;
    --status-drafting-mark: #B0B1B1;
    --status-drafting-ink: #BCBEBD;
    --status-applied-bg: #153143;
    --status-applied-mark: #6FBAED;
    --status-applied-ink: #7CC7FB;
    --status-screen-bg: #1F2E45;
    --status-screen-mark: #87B3F4;
    --status-screen-ink: #95C0FF;
    --status-assessment-bg: #282B45;
    --status-assessment-mark: #A1ABF3;
    --status-assessment-ink: #AEB8FE;
    --status-interviewing-bg: #312842;
    --status-interviewing-mark: #B9A3EB;
    --status-interviewing-ink: #C6AFF9;
    --status-final-bg: #3A253B;
    --status-final-mark: #D39AD6;
    --status-final-ink: #E0A6E3;
    --status-offer-bg: #1E341F;
    --status-offer-mark: #86C387;
    --status-offer-ink: #92D094;
    --status-accepted-bg: #163526;
    --status-accepted-mark: #71C69A;
    --status-accepted-ink: #7ED3A6;
    --status-declined-bg: #3B2730;
    --status-declined-mark: #D69EB8;
    --status-declined-ink: #E3ABC4;
    --status-withdrawn-bg: #2D2E2E;
    --status-withdrawn-mark: #B0B1B1;
    --status-withdrawn-ink: #BDBEBD;
    --status-rejected-bg: #432422;
    --status-rejected-mark: #EC968F;
    --status-rejected-ink: #FAA39C;
    --status-noresponse-bg: #2C3024;
    --status-noresponse-mark: #ADB695;
    --status-noresponse-ink: #B9C3A1;
    --status-jobclosed-bg: #352C26;
    --status-jobclosed-mark: #C5AB9D;
    --status-jobclosed-ink: #D2B7A9;
  }
}
@media screen {
  :root[data-theme=dark] {
    color-scheme: dark;
    --surface: #1B1C18;
    --surface-raised: #23241F;
    --surface-sunken: #141511;
    --border: #35362F;
    --border-control: #84867A;
    --text: #D9D4C6;
    --text-muted: #A7A396;
    --accent: #B3A991;
    --accent-strong: #C9C0A9;
    --text-on-accent: #1C1B16;
    --success: #A3D19B;
    --text-on-success: #10240D;
    --danger: #F4A097;
    --danger-strong: #F9C4BD;
    --text-on-danger: #3A0B06;
    --focus-ring: #B3A991;
    --accent-soft: #2D2D25;
    --warning: #F2A26A;
    --text-on-warning: #2A1405;
    --warning-soft: #2E2319;
    --mark: #D4A93C;
    --scrim: rgb(0 0 0 / 0.6);
    --coach: #2B776F;
    --coach-strong: #246F68;
    --text-on-coach: #F4F0E6;
    --coach-lip: #7CC2B6;
    /* A thin light teal ring, as Violet's gold trim, so the night Coach keeps a 3:1 edge on a raised card, where its
       fill is 2.96:1 (R104). The fill and its cream words stay. */
    --coach-trim: #7CC2B6;
    --coach-glow: 0 0 0 3px rgb(43 119 111 / 0.3), 0 0 16px 3px rgb(56 150 140 / 0.4);
    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.45);
    --shadow-2: 0 1px 2px rgb(0 0 0 / 0.4), 0 10px 28px rgb(0 0 0 / 0.45);
    --shadow-3: 0 2px 6px rgb(0 0 0 / 0.5), 0 18px 48px rgb(0 0 0 / 0.6);
    --status-drafting-bg: #2D2E2E;
    --status-drafting-mark: #B0B1B1;
    --status-drafting-ink: #BCBEBD;
    --status-applied-bg: #153143;
    --status-applied-mark: #6FBAED;
    --status-applied-ink: #7CC7FB;
    --status-screen-bg: #1F2E45;
    --status-screen-mark: #87B3F4;
    --status-screen-ink: #95C0FF;
    --status-assessment-bg: #282B45;
    --status-assessment-mark: #A1ABF3;
    --status-assessment-ink: #AEB8FE;
    --status-interviewing-bg: #312842;
    --status-interviewing-mark: #B9A3EB;
    --status-interviewing-ink: #C6AFF9;
    --status-final-bg: #3A253B;
    --status-final-mark: #D39AD6;
    --status-final-ink: #E0A6E3;
    --status-offer-bg: #1E341F;
    --status-offer-mark: #86C387;
    --status-offer-ink: #92D094;
    --status-accepted-bg: #163526;
    --status-accepted-mark: #71C69A;
    --status-accepted-ink: #7ED3A6;
    --status-declined-bg: #3B2730;
    --status-declined-mark: #D69EB8;
    --status-declined-ink: #E3ABC4;
    --status-withdrawn-bg: #2D2E2E;
    --status-withdrawn-mark: #B0B1B1;
    --status-withdrawn-ink: #BDBEBD;
    --status-rejected-bg: #432422;
    --status-rejected-mark: #EC968F;
    --status-rejected-ink: #FAA39C;
    --status-noresponse-bg: #2C3024;
    --status-noresponse-mark: #ADB695;
    --status-noresponse-ink: #B9C3A1;
    --status-jobclosed-bg: #352C26;
    --status-jobclosed-mark: #C5AB9D;
    --status-jobclosed-ink: #D2B7A9;
  }
}
/* Violet by day (REPORT 3.4). Screen only, like the dark blocks, so a printed page is never violet. It must come after
   Slate's night blocks: the selectors are equally specific, so the order decides, and a Violet page at night takes
   Violet's day roles over Slate's night ones before Violet's own night roles below. */
@media screen {
  :root[data-palette=violet] {
    --surface: #F8F6FB;
    --surface-raised: #FFFFFF;
    --surface-sunken: #EEEAF4;
    --border: #DDD7E7;
    --border-control: #7E7690;
    --text: #1C1826;
    --text-muted: #59526A;
    --accent: #2E2150;
    --accent-strong: #21173B;
    --text-on-accent: #FFFFFF;
    --success: #1E7A4A;
    --text-on-success: #FFFFFF;
    --danger: #BE2338;
    --danger-strong: #8E1828;
    --text-on-danger: #FFFFFF;
    --focus-ring: #2E2150;
    --accent-soft: #E9E6F0;
    --warning: #A84F0C;
    --text-on-warning: #FFFFFF;
    --warning-soft: #FCEBE1;
    --mark: #6A3FC1;
    --scrim: rgb(22 18 32 / 0.45);
    --coach: #4A2BB5;
    --coach-strong: #3D2396;
    --text-on-coach: #FFFFFF;
    --coach-lip: #E8B845;
    --coach-trim: #E8B845;
    --coach-glow: 0 0 14px 2px rgb(200 150 30 / 0.35);
    --status-drafting-bg: #E5E6E6;
    --status-drafting-mark: #797B7A;
    --status-drafting-ink: #5C5E5D;
    --status-applied-bg: #D4E9FF;
    --status-applied-mark: #2B7EC9;
    --status-applied-ink: #0460A5;
    --status-screen-bg: #C8EDFE;
    --status-screen-mark: #0686AE;
    --status-screen-ink: #066786;
    --status-assessment-bg: #B9F2F9;
    --status-assessment-mark: #068B96;
    --status-assessment-ink: #086A73;
    --status-interviewing-bg: #BCF4E9;
    --status-interviewing-mark: #0B8E7F;
    --status-interviewing-ink: #006D61;
    --status-final-bg: #FFD9F3;
    --status-final-mark: #AD5697;
    --status-final-ink: #8D3879;
    --status-offer-bg: #CFF1CF;
    --status-offer-mark: #3A8F42;
    --status-offer-ink: #157123;
    --status-accepted-bg: #C5F3D9;
    --status-accepted-mark: #06915F;
    --status-accepted-ink: #027048;
    --status-declined-bg: #FDDDE2;
    --status-declined-mark: #A56571;
    --status-declined-ink: #854854;
    --status-withdrawn-bg: #E6E6E6;
    --status-withdrawn-mark: #797B7A;
    --status-withdrawn-ink: #5C5E5D;
    --status-rejected-bg: #FEDDDA;
    --status-rejected-mark: #BF534E;
    --status-rejected-ink: #9D3533;
    --status-noresponse-bg: #E4E9D6;
    --status-noresponse-mark: #758055;
    --status-noresponse-ink: #596339;
    --status-jobclosed-bg: #F2E3DA;
    --status-jobclosed-mark: #937260;
    --status-jobclosed-ink: #755645;
  }
}
/* Violet at night, the same two ways as Slate's: a device that prefers dark while the account says System, and Dark
   chosen on the account. */
@media screen and (prefers-color-scheme: dark) {
  :root[data-palette=violet]:not([data-theme=light]) {
    color-scheme: dark;
    --surface: #16131F;
    --surface-raised: #201C2C;
    --surface-sunken: #100E17;
    --border: #332D44;
    --border-control: #847C99;
    --text: #ECE8F4;
    --text-muted: #ABA3BF;
    --accent: #B3A8D1;
    --accent-strong: #C9C0E2;
    --text-on-accent: #16131F;
    --success: #7FD8A4;
    --text-on-success: #062413;
    --danger: #FF8F9A;
    --danger-strong: #FFB8BF;
    --text-on-danger: #3A0710;
    --focus-ring: #B3A8D1;
    --accent-soft: #2A2536;
    --warning: #F2A26A;
    --text-on-warning: #2A1405;
    --warning-soft: #2F2219;
    --mark: #B79CFF;
    --scrim: rgb(0 0 0 / 0.6);
    --coach: #4B3A8F;
    --coach-strong: #5A48A3;
    --text-on-coach: #FFFFFF;
    --coach-lip: #E8B845;
    --coach-trim: #E8B845;
    --coach-glow: 0 0 16px 3px rgb(232 184 69 / 0.4);
    --status-drafting-bg: #2D2E2E;
    --status-drafting-mark: #B0B1B1;
    --status-drafting-ink: #BCBEBD;
    --status-applied-bg: #1A2F45;
    --status-applied-mark: #7CB6F1;
    --status-applied-ink: #89C3FF;
    --status-screen-bg: #0F3240;
    --status-screen-mark: #61BEE6;
    --status-screen-ink: #6ECBF3;
    --status-assessment-bg: #063439;
    --status-assessment-mark: #4FC4D1;
    --status-assessment-ink: #5ED1DE;
    --status-interviewing-bg: #0A3530;
    --status-interviewing-mark: #57C7B6;
    --status-interviewing-ink: #65D4C3;
    --status-final-bg: #3D2436;
    --status-final-mark: #DD97C8;
    --status-final-ink: #EAA3D5;
    --status-offer-bg: #1E341F;
    --status-offer-mark: #86C387;
    --status-offer-ink: #92D094;
    --status-accepted-bg: #163526;
    --status-accepted-mark: #71C69A;
    --status-accepted-ink: #7ED3A6;
    --status-declined-bg: #3B282B;
    --status-declined-mark: #D5A1A9;
    --status-declined-ink: #E3ADB6;
    --status-withdrawn-bg: #2D2E2E;
    --status-withdrawn-mark: #B0B1B1;
    --status-withdrawn-ink: #BDBEBD;
    --status-rejected-bg: #432422;
    --status-rejected-mark: #EC968F;
    --status-rejected-ink: #FAA39C;
    --status-noresponse-bg: #2C3024;
    --status-noresponse-mark: #ADB695;
    --status-noresponse-ink: #B9C3A1;
    --status-jobclosed-bg: #352C26;
    --status-jobclosed-mark: #C5AB9D;
    --status-jobclosed-ink: #D2B7A9;
  }
}
@media screen {
  :root[data-palette=violet][data-theme=dark] {
    color-scheme: dark;
    --surface: #16131F;
    --surface-raised: #201C2C;
    --surface-sunken: #100E17;
    --border: #332D44;
    --border-control: #847C99;
    --text: #ECE8F4;
    --text-muted: #ABA3BF;
    --accent: #B3A8D1;
    --accent-strong: #C9C0E2;
    --text-on-accent: #16131F;
    --success: #7FD8A4;
    --text-on-success: #062413;
    --danger: #FF8F9A;
    --danger-strong: #FFB8BF;
    --text-on-danger: #3A0710;
    --focus-ring: #B3A8D1;
    --accent-soft: #2A2536;
    --warning: #F2A26A;
    --text-on-warning: #2A1405;
    --warning-soft: #2F2219;
    --mark: #B79CFF;
    --scrim: rgb(0 0 0 / 0.6);
    --coach: #4B3A8F;
    --coach-strong: #5A48A3;
    --text-on-coach: #FFFFFF;
    --coach-lip: #E8B845;
    --coach-trim: #E8B845;
    --coach-glow: 0 0 16px 3px rgb(232 184 69 / 0.4);
    --status-drafting-bg: #2D2E2E;
    --status-drafting-mark: #B0B1B1;
    --status-drafting-ink: #BCBEBD;
    --status-applied-bg: #1A2F45;
    --status-applied-mark: #7CB6F1;
    --status-applied-ink: #89C3FF;
    --status-screen-bg: #0F3240;
    --status-screen-mark: #61BEE6;
    --status-screen-ink: #6ECBF3;
    --status-assessment-bg: #063439;
    --status-assessment-mark: #4FC4D1;
    --status-assessment-ink: #5ED1DE;
    --status-interviewing-bg: #0A3530;
    --status-interviewing-mark: #57C7B6;
    --status-interviewing-ink: #65D4C3;
    --status-final-bg: #3D2436;
    --status-final-mark: #DD97C8;
    --status-final-ink: #EAA3D5;
    --status-offer-bg: #1E341F;
    --status-offer-mark: #86C387;
    --status-offer-ink: #92D094;
    --status-accepted-bg: #163526;
    --status-accepted-mark: #71C69A;
    --status-accepted-ink: #7ED3A6;
    --status-declined-bg: #3B282B;
    --status-declined-mark: #D5A1A9;
    --status-declined-ink: #E3ADB6;
    --status-withdrawn-bg: #2D2E2E;
    --status-withdrawn-mark: #B0B1B1;
    --status-withdrawn-ink: #BDBEBD;
    --status-rejected-bg: #432422;
    --status-rejected-mark: #EC968F;
    --status-rejected-ink: #FAA39C;
    --status-noresponse-bg: #2C3024;
    --status-noresponse-mark: #ADB695;
    --status-noresponse-ink: #B9C3A1;
    --status-jobclosed-bg: #352C26;
    --status-jobclosed-mark: #C5AB9D;
    --status-jobclosed-ink: #D2B7A9;
  }
}
/* Whatever the scheme on screen, paper is printed light. */
@media print {
  :root,
  :root[data-theme] {
    color-scheme: light;
  }
}
/* US Letter, for any page printed. Custom properties do not reach an @page rule, so its size and margin are
   written here, with the tokens, and nowhere else. */
@page {
  size: letter;
  margin: 0.6in;
}
/* @fileoverview The three faces the type roles name (REPORT 3.6 and 6.4): Lexend Light for --font-display, Public
   Sans for --font-sans and --font-voice, Spectral for --font-doc and --font-accent. They come from their @fontsource
   packages (R103) and the app serves them itself under /fonts/, before sign-in (src/fonts.js, which lists the same
   addresses); never from another site, so no address in this file or the compiled stylesheet names a scheme or a
   host (test/fonts.test.js). The latin subset in WOFF2. font-display: swap shows the words at once in the fallback
   face that follows each name in its token, then in the face once it has loaded. */
/* Titles, section heads, company names, the wordmark: the one weight the design uses. */
@font-face {
  font-family: "Lexend";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("/fonts/lexend/lexend-latin-300-normal.woff2") format("woff2");
}
/* Everything a person operates, and the Coach's words: the variable roman, one file for every weight, so the 650 of
   --weight-bold is drawn as 650 and not rounded to a fixed bold. */
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/public-sans/public-sans-latin-wght-normal.woff2") format("woff2");
}
/* The resume paper and a letter: regular, and semibold, which a bold of 650 resolves to. */
@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/spectral/spectral-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/spectral/spectral-latin-600-normal.woff2") format("woff2");
}
/* The one decorative italic (--font-accent), and the year line under each job on the resume paper (S10). */
@font-face {
  font-family: "Spectral";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/spectral/spectral-latin-400-italic.woff2") format("woff2");
}
/* @fileoverview Element defaults and the helpers every page shares (the v0 design, REPORT 4.2.1 and 4.2.2; the
   restyle's steps 3 and 4): body text, titles and heads, paragraphs and lists, links and the links that stand on
   their own, the one focus style, the sprite's icons (views/partials/icons.ejs), words read out but not seen, small
   capitals, the skip link, and reduced motion: the account's setting (data-motion on the html element,
   views/partials/top.ejs), or the device's preference when the setting is System. */
/* @fileoverview The mixins every partial shares (REPORT 4.1.1, S1), @use'd by the partials that need them; this
   header is all it writes into public/css/app.css. A mixin compiles to exactly what the tests read there, so the
   at-rules here are the ones the theme test pins. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* Body text: Public Sans at 16/1.55 in --text, smoothed in grayscale on a Mac as the boards draw it. Long words, URLs
   and pasted text wrap instead of overflowing. */
body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading);
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The hidden attribute wins over any display a class sets, such as .button's inline-flex, so a control the script
   has not shown yet stays hidden without JavaScript. */
[hidden] {
  display: none !important;
}

/* Titles and heads in the display face, Lexend Light (REPORT 3.6, 4.2.1). */
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  line-height: var(--leading-tight);
  text-wrap: balance;
  margin: 0 0 var(--space-4);
}

/* A word set off in a title is the one decorative italic (S10, D20). */
:is(h1, h2, h3) em {
  font-family: var(--font-accent);
  font-style: italic;
}

/* A page title: 40px on a Mac, 32px on a phone (REPORT 3.6). */
h1 {
  font-size: var(--text-3xl);
}
@media (max-width: 37.5em) {
  h1 {
    font-size: var(--text-2xl);
  }
}

h2 {
  font-size: var(--text-xl);
}

h3 {
  font-size: var(--text-lg);
}

/* Paragraphs and lists, a step apart. A paragraph keeps to the reading width and wraps without a lone last word; a
   list's items sit a little in from its edge. At no weight (:where), so a part's own margins and widths always win. */
:where(p, ul, ol, dl) {
  margin: 0 0 var(--space-4);
}

:where(p) {
  max-width: var(--measure);
  text-wrap: pretty;
}

:where(ul, ol) {
  padding-left: var(--space-5);
}

:where(dd) {
  margin: 0;
}

/* Links in running text: the accent, underlined just clear of the descenders, the line thickening under the pointer
   and the accent's strong shade under the pointer or the finger (REPORT 4.2.2). At no weight (:where), so a link with
   a class of its own (a button, a navigation link, a row) always sets its own color and line. */
:where(a) {
  color: var(--accent);
  text-decoration-line: underline;
  text-decoration-thickness: var(--underline-width);
  text-underline-offset: var(--underline-offset);
  transition: color var(--dur-fast) var(--ease), text-decoration-thickness var(--dur-fast) var(--ease);
}

@media (hover: hover) {
  :where(a:hover) {
    color: var(--accent-strong);
    text-decoration-thickness: var(--underline-width-hover);
  }
}
:where(a:active) {
  color: var(--accent-strong);
}

/* A link that stands on its own, outside a sentence: the words stay a link, and the target grows to 44px around them
   (agent/ui-standards.md). */
.link-target {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  min-width: var(--touch-min);
}

/* One that leaves the app: its words, then #i-external, and a visually hidden "(opens in a new tab)".
   <a class="link-target link-target--external" href=".." target="_blank" rel="noopener">Open the posting<svg
   class="icon" aria-hidden="true"><use href="#i-external"/></svg><span class="visually-hidden">(opens in a new
   tab)</span></a> */
.link-target--external {
  gap: var(--space-1);
}

.link-target--external > .icon {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

/* Back to the list, above a record's title: 14px medium in --text-muted, its chevron first, --text under the pointer
   or the finger.
   <a class="back-link" href="/applications"><svg class="icon icon--sm" aria-hidden="true"><use
   href="#i-chevron-left"/></svg>Applications</a> */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--touch-min);
  margin-left: calc(-1 * var(--space-1));
  padding-right: var(--space-2);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
}

@media (hover: hover) {
  .back-link:hover {
    color: var(--text);
  }
}
.back-link:active {
  color: var(--text);
}

/* The page a section sums up, as a link standing on its own: 14px medium in the accent, then #i-chevron-right; a 44px
   target ("All applications", "Calendar", "All conversations"; the board's .home__more, .week__more and
   .coach-sheet__all).
   <a class="link-more" href="/calendar">Calendar<svg class="icon" aria-hidden="true"><use
   href="#i-chevron-right"/></svg></a> */
.link-more {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--space-1) / 2);
  min-height: var(--touch-min);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.link-more > .icon {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

code,
pre {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

/* The one focus style for every control. Never add a second one or remove an outline. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* An icon from the sprite, in the color of the words around it: 1.25em, 20px in body text, or --icon-sm and --icon-lg
   where a part says so (REPORT 4.1.5). <svg class="icon" aria-hidden="true"><use href="#i-name"/></svg>. The Coach's
   #i-coach keeps its own colors. */
.icon {
  display: inline-block;
  flex: none;
  width: var(--icon-size);
  height: var(--icon-size);
  vertical-align: middle;
}

.icon--sm {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

.icon--lg {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

/* The sprite (views/partials/icons.ejs) takes no room and is never seen, but it is rendered, never display: none: the
   Coach avatar's gradient is not painted from a sprite that is not rendered. */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* Read out, not seen: words a screen reader needs that the page shows another way. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Small capitals: the label over a group ("This week", a table's column names). A code inside keeps its case. */
.caps {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.caps code {
  font-size: inherit;
  letter-spacing: 0;
  text-transform: none;
}

.skip-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  position: absolute;
  left: var(--space-4);
  top: calc(-1 * var(--space-8));
  z-index: var(--z-skip-link);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: var(--weight-bold);
  text-decoration: none;
}

.skip-link:focus {
  top: var(--space-2);
}

/* The first paragraph under a page title: 18px in --text-muted, at the reading width. */
.lead {
  max-width: var(--measure);
  color: var(--text-muted);
  font-size: var(--text-md);
}

.muted {
  color: var(--text-muted);
}

/* Pasted text such as a posting keeps its line breaks. */
.pre-wrap {
  white-space: pre-wrap;
}

/* Reduced motion, by one rule in two places: the device asks for it and the account has not chosen Full, or the
   account has chosen Reduced. Every transition and animation stops at once, on every element and its ::before and
   ::after, and on the ::backdrop a dialog's scrim fades in on and the ::file-selector-button of a file field, which has
   a transition (S13); scrolling jumps instead of gliding. Those two pseudo-elements are rules of their own, so a
   browser that does not know one drops only that rule, never the list with every element in it. Keep the two blocks
   the same (test/css-theme.test.js). */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion=full]),
  :root:not([data-motion=full]) *,
  :root:not([data-motion=full]) *::before,
  :root:not([data-motion=full]) *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  :root:not([data-motion=full]) *::backdrop {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  :root:not([data-motion=full]) *::file-selector-button {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
:root[data-motion=reduced],
:root[data-motion=reduced] *,
:root[data-motion=reduced] *::before,
:root[data-motion=reduced] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

:root[data-motion=reduced] *::backdrop {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

:root[data-motion=reduced] *::file-selector-button {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* @fileoverview The page frame: header and navigation, the content column, the footer. */
.site-header {
  border-bottom: var(--border-width) solid var(--border);
  background: var(--surface-raised);
}

.site-header__inner,
.site-footer__inner,
.page {
  max-width: var(--page-width);
  margin: 0 auto;
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  min-height: var(--space-8);
}

.site-header__name {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  color: var(--text);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  text-decoration: none;
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
}

.site-nav__form {
  display: inline;
  margin: 0;
}

.site-nav__button {
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}

/* On a phone the links sit closer, so the seven of them take two lines under the app's name instead of three. Each
   is still at least 44px tall and wider than that. The same 600px as the tables' (styles/_tables.scss). */
@media (max-width: 37.5em) {
  .site-nav__link {
    padding: 0 var(--space-2);
  }
}
.site-nav__link[aria-current=page] {
  font-weight: var(--weight-bold);
  text-decoration: underline;
  text-underline-offset: var(--underline-offset-current);
}

@media (hover: hover) {
  .site-nav__link:hover {
    background: var(--surface-sunken);
  }
}
.site-nav__link:active {
  background: var(--surface-sunken);
}

.page {
  padding-top: var(--space-6);
  padding-bottom: var(--space-7);
}

.site-footer {
  border-top: var(--border-width) solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: var(--space-8);
}

.site-footer__version {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-min);
  min-width: var(--touch-min);
  padding: 0 var(--space-2);
  color: var(--text-muted);
}

.section {
  margin-bottom: var(--space-7);
}

.totals {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  margin: 0 0 var(--space-4);
}

.totals__item dt {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.totals__item dd {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
}

.toc__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  margin: 0 0 var(--space-6);
  padding: 0;
  list-style: none;
}

.toc__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-min);
  min-width: var(--touch-min);
}

.actions-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.tabs__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: var(--space-5) 0 var(--space-4);
  padding: 0;
  border-bottom: var(--border-width) solid var(--border);
  list-style: none;
}

.tabs__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0 var(--space-4);
  color: var(--text);
  text-decoration: none;
}

.tabs__link[aria-current=page] {
  font-weight: var(--weight-bold);
  box-shadow: inset 0 calc(-1 * var(--focus-width)) 0 var(--accent);
}

.posting {
  max-width: var(--measure);
  padding: var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

/* A cell's own link gets a full-size target, as .link-target does (styles/_base.scss); its look in --text comes with
   the tables (REPORT 4.2.2, 6.3 step 13). */
.table__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  min-width: var(--touch-min);
}

/* The posting analysis (P1-09): plain lists, the terms worth echoing as a wrapped row, and the names offer. */
.analysis-list {
  max-width: var(--measure);
  margin: 0 0 var(--space-5);
  padding-left: var(--space-5);
}

.analysis-list li {
  margin-bottom: var(--space-1);
}

.analysis-list--terms {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-left: 0;
  list-style: none;
}

.analysis-list--terms li {
  margin: 0;
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  font-size: var(--text-sm);
}

.suggestion {
  max-width: var(--measure);
  margin: 0 0 var(--space-5);
  padding: var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
}

/* The tailored resume (P1-10): the preview as a page, with the gaps and notes beside it on a wide screen and
   under it on a narrow one. */
.resume-layout {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}

.resume-preview {
  flex: 3 1 var(--measure);
  min-width: 0;
  padding: var(--space-5);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-1);
}

.resume-preview h3 {
  margin: var(--space-5) 0 var(--space-2);
  padding-bottom: var(--space-1);
  border-bottom: var(--border-width) solid var(--border);
  font-size: var(--text-base);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

.resume-preview h4 {
  margin: 0;
  font-size: var(--text-base);
}

.resume-preview__name {
  margin-bottom: var(--space-1);
}

.resume-preview__headline {
  margin: 0 0 var(--space-1);
  font-weight: var(--weight-bold);
}

.resume-preview__contact,
.resume-preview__meta {
  margin: 0 0 var(--space-2);
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.resume-preview__entry {
  margin-bottom: var(--space-4);
}

.resume-preview__entry ul,
.resume-preview__skills {
  margin: 0;
  padding-left: var(--space-5);
}

.resume-aside {
  flex: 1 1 var(--field-min);
  min-width: 0;
}

.resume-aside h2 {
  font-size: var(--text-lg);
}

.versions {
  padding-left: var(--space-5);
}

.release {
  margin-bottom: var(--space-6);
}

/* The release's date sits in its h2 but is not a title: the interface face, as the board draws it, not the heading's
   Lexend Light (REPORT 3.6). */
.release__date {
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--weight-normal);
}

.release__where {
  font-weight: var(--weight-bold);
}

/* @fileoverview Buttons: at least 44px, hover only where there is a pointer that hovers, and a press state; the old
   app's look (square-ish 4px corners, bold words, a raised fill for the plain button); and the working state of a
   button whose call to Claude is under way. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  min-width: var(--touch-min);
  padding: 0 var(--space-4);
  border: var(--border-width) solid var(--border-control);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--text);
  font: inherit;
  font-weight: var(--weight-bold);
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.button--primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--text-on-accent);
}

.button--danger {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--text-on-danger);
}

.button:disabled {
  cursor: not-allowed;
  opacity: var(--opacity-disabled);
}

@media (hover: hover) {
  .button:hover:not(:disabled) {
    background: var(--surface-sunken);
  }
  .button--primary:hover:not(:disabled) {
    background: var(--accent-strong);
  }
  .button--danger:hover:not(:disabled) {
    background: var(--danger-strong);
  }
}
.button:active:not(:disabled) {
  background: var(--surface-sunken);
}

.button--primary:active:not(:disabled) {
  background: var(--accent-strong);
}

.button--danger:active:not(:disabled) {
  background: var(--danger-strong);
}

/* A button whose call is under way (public/js/stream-form.js, chat.js and usage.js set data-working on the button
   pressed, and take it off when the call ends): still disabled, so a second press does not pay twice, but drawn at
   full strength with a turning mark after its words, so it reads as working rather than unavailable. The mark is
   decoration (the status line under the button says what is happening), and it stands still under reduced motion. */
.button[data-working] {
  cursor: progress;
}

.button[data-working]:disabled {
  opacity: 1;
}

.button[data-working]::after {
  content: "";
  flex: none;
  width: var(--working-size);
  height: var(--working-size);
  border: var(--working-width) solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: working-turn var(--dur-turn) linear infinite;
}

@keyframes working-turn {
  to {
    transform: rotate(1turn);
  }
}
/* @fileoverview Forms: labelled fields with the old app's 4px corners and an edge that stands out from the page, and a
   refused form's note beside the button and under each field. */
.field {
  display: grid;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
  max-width: var(--measure);
}

.field__label {
  font-weight: var(--weight-bold);
}

.field__hint {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.input,
.textarea,
.select {
  width: 100%;
  min-height: var(--touch-min);
  padding: var(--space-2) var(--space-3);
  border: var(--border-width) solid var(--border-control);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}

.textarea {
  min-height: calc(var(--touch-min) * 4);
  resize: vertical;
}

.input[aria-invalid=true],
.textarea[aria-invalid=true],
.select[aria-invalid=true] {
  border-color: var(--danger);
}

.field__error,
.form__note {
  color: var(--danger);
  font-size: var(--text-sm);
}

.notice {
  padding: var(--space-3) var(--space-4);
  border: var(--border-width) solid var(--success);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  max-width: var(--measure);
}

.notice--mock {
  border-color: var(--accent);
}

.notice--warning {
  border-color: var(--danger);
}

.stream-status,
.progress-status {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* Says a call to Claude is under way (public/js/import.js). Always in the page, so it is read out; no room while empty. */
.progress-status:empty {
  margin: 0;
}

/* A file field: the browser draws its own button inside, so less padding than a text field. */
.input--file {
  padding: var(--space-2);
}

.stream-output {
  min-height: calc(var(--touch-min) * 2);
  max-width: var(--measure);
  padding: var(--space-3) var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  white-space: pre-wrap;
}

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--field-min), 1fr));
  gap: 0 var(--space-4);
  max-width: var(--measure);
}

/* A group of radio buttons under one label, such as the cover letter's length (P1-14). */
.choice {
  min-width: 0;
  max-width: var(--measure);
  margin: 0 0 var(--space-4);
  padding: 0;
  border: 0;
}

.choice legend {
  margin-bottom: var(--space-1);
  padding: 0;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  margin-bottom: var(--space-3);
  cursor: pointer;
}

.checkbox input {
  width: var(--space-5);
  height: var(--space-5);
  margin: 0;
  accent-color: var(--accent);
}

.entry-list {
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
  max-width: var(--measure);
}

.entry {
  margin-bottom: var(--space-4);
  padding: var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
}

.entry__heading {
  font-size: var(--text-lg);
}

.entry__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2) var(--space-4);
}

.entry__order-field {
  max-width: var(--field-narrow);
  margin-bottom: 0;
}

.entry__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Says what Remove did (public/js/profile.js), in the removed entry's place. Always in the page, so it is read out;
   takes no room while empty. */
.entry__status {
  margin: 0;
}

/* A removed entry waits for the save as the line that says so, where the entry was, so the person sees it beside the
   entry that takes the focus. Its fields stay in the form, ticked to be removed. */
.entry--removed {
  padding-block: var(--space-2);
  border-style: dashed;
}

.entry--removed > :not(.entry__status) {
  display: none;
}

/* With JavaScript the buttons do the ordering and removing, so the order number and the Remove box are not shown. */
.js .entry__order-field,
.js .entry__remove-field {
  display: none;
}

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* @fileoverview The statuses (R45, R67; REPORT 3.5, 4.8): the color in the app. The chip is a pill on its status's
   ground with its words in --text, and before them a mark: a filled dot while the application is in progress, a ring
   once it is closed. The label always carries the meaning; color never does alone. Views write
   `status status--<%= key %>` with the app's own keys (src/schemas/application.js); the tokens use shorter keys, and
   a Sass map here joins them, so the views need no change. A modifier only sets three private properties, a ground, a
   mark and an ink, so it can sit on anything that draws a status's color (REPORT 4.8.5). The status control, its
   menu, the counts by status and .status-saved come with the steps that draw them (REPORT 6.3, steps 13 and 20). */
.status {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: var(--space-2);
  min-height: var(--status-height);
  margin: 0;
  padding: var(--status-pad-block) var(--space-3) var(--status-pad-block) var(--status-pad-start);
  border-radius: var(--radius-pill);
  background: var(--_status-bg, var(--surface-sunken));
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  color: var(--text);
  white-space: nowrap;
  vertical-align: middle;
}

.status::before {
  content: "";
  flex: none;
  width: var(--status-dot);
  height: var(--status-dot);
  border-radius: 50%;
  background: var(--_status-mark, var(--text-muted));
}

.status--drafting {
  --_status-bg: var(--status-drafting-bg);
  --_status-mark: var(--status-drafting-mark);
  --_status-ink: var(--status-drafting-ink);
}

.status--applied {
  --_status-bg: var(--status-applied-bg);
  --_status-mark: var(--status-applied-mark);
  --_status-ink: var(--status-applied-ink);
}

.status--phone_screen {
  --_status-bg: var(--status-screen-bg);
  --_status-mark: var(--status-screen-mark);
  --_status-ink: var(--status-screen-ink);
}

.status--assessment {
  --_status-bg: var(--status-assessment-bg);
  --_status-mark: var(--status-assessment-mark);
  --_status-ink: var(--status-assessment-ink);
}

.status--interview_scheduled {
  --_status-bg: var(--status-interviewing-bg);
  --_status-mark: var(--status-interviewing-mark);
  --_status-ink: var(--status-interviewing-ink);
}

.status--final_round {
  --_status-bg: var(--status-final-bg);
  --_status-mark: var(--status-final-mark);
  --_status-ink: var(--status-final-ink);
}

.status--offer_received {
  --_status-bg: var(--status-offer-bg);
  --_status-mark: var(--status-offer-mark);
  --_status-ink: var(--status-offer-ink);
}

.status--offer_accepted {
  --_status-bg: var(--status-accepted-bg);
  --_status-mark: var(--status-accepted-mark);
  --_status-ink: var(--status-accepted-ink);
}

.status--offer_declined {
  --_status-bg: var(--status-declined-bg);
  --_status-mark: var(--status-declined-mark);
  --_status-ink: var(--status-declined-ink);
}

.status--withdrawn {
  --_status-bg: var(--status-withdrawn-bg);
  --_status-mark: var(--status-withdrawn-mark);
  --_status-ink: var(--status-withdrawn-ink);
}

.status--rejected {
  --_status-bg: var(--status-rejected-bg);
  --_status-mark: var(--status-rejected-mark);
  --_status-ink: var(--status-rejected-ink);
}

.status--no_response {
  --_status-bg: var(--status-noresponse-bg);
  --_status-mark: var(--status-noresponse-mark);
  --_status-ink: var(--status-noresponse-ink);
}

.status--job_closed {
  --_status-bg: var(--status-jobclosed-bg);
  --_status-mark: var(--status-jobclosed-mark);
  --_status-ink: var(--status-jobclosed-ink);
}

.status--offer_accepted:is(.status, .status-tally__item)::before {
  background: transparent;
  box-shadow: inset 0 0 0 var(--status-ring) var(--_status-mark);
}

.status--offer_declined:is(.status, .status-tally__item)::before {
  background: transparent;
  box-shadow: inset 0 0 0 var(--status-ring) var(--_status-mark);
}

.status--withdrawn:is(.status, .status-tally__item)::before {
  background: transparent;
  box-shadow: inset 0 0 0 var(--status-ring) var(--_status-mark);
}

.status--rejected:is(.status, .status-tally__item)::before {
  background: transparent;
  box-shadow: inset 0 0 0 var(--status-ring) var(--_status-mark);
}

.status--no_response:is(.status, .status-tally__item)::before {
  background: transparent;
  box-shadow: inset 0 0 0 var(--status-ring) var(--_status-mark);
}

.status--job_closed:is(.status, .status-tally__item)::before {
  background: transparent;
  box-shadow: inset 0 0 0 var(--status-ring) var(--_status-mark);
}

.status.status--quiet {
  min-height: 0;
  padding: 0;
  background: transparent;
}

.status[data-pill] {
  min-height: 0;
  padding: var(--status-pad-block) var(--space-2) var(--status-pad-block) var(--status-pad-start-xs);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.status[data-pill]::before {
  width: var(--status-dot-xs);
  height: var(--status-dot-xs);
}

/* @fileoverview Tables of records (the applications, the AI calls, past imports). On a wide screen, a table that scrolls
   inside its box if it must. On a phone (below 600px), each row becomes one block and each cell a line with its
   column's name beside it, from the cell's data-label, which the template prints from the same list as the header
   (P2-07). The page's tables also carry their roles (table, rowgroup, row, columnheader, cell), because a browser that
   draws table parts as blocks may stop telling a screen reader it is a table; with the roles it stays one, header
   cells included. */
.table-wrap {
  max-width: 100%;
  overflow-x: auto;
  margin-bottom: var(--space-5);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.table th,
.table td {
  overflow-wrap: normal;
  white-space: nowrap;
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-width) solid var(--border);
  text-align: left;
  /* Baseline, so a cell's text lines up with a 44px link's text in the next cell. */
  vertical-align: baseline;
}

.table th {
  color: var(--text-muted);
  font-weight: var(--weight-bold);
}

/* The phone breakpoint, the stylesheet's one width breakpoint (the top bar's links use it too): 600px at the default
   text size, in em so it moves with a larger text setting. Custom properties do not reach a media query, so it is
   written where it is used. */
@media (max-width: 37.5em) {
  .table--stack,
  .table--stack tbody,
  .table--stack tr,
  .table--stack td {
    display: block;
  }
  /* The header row is out of sight but still read: each cell shows its own column's name instead. */
  .table--stack thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .table--stack tr {
    padding: var(--space-2) 0;
    border-bottom: var(--border-width) solid var(--border);
  }
  /* Two columns, the name and the value. Each of the app's cells holds one thing (a word, a link, a date), which is
     the value; a cell holding words and elements side by side would need a wrapper around them. */
  .table--stack td {
    display: grid;
    grid-template-columns: var(--cell-label) minmax(0, 1fr);
    gap: var(--space-3);
    align-items: baseline;
    padding: var(--space-1) 0;
    border-bottom: 0;
    overflow-wrap: anywhere;
    white-space: normal;
  }
  /* The column's name, seen but not read out a second time where the browser takes the alternative text after the
     slash; one that does not reads the name, as the line's label. */
  .table--stack td::before {
    content: attr(data-label);
    content: attr(data-label)/"";
    color: var(--text-muted);
    font-weight: var(--weight-bold);
  }
  /* A cell with nothing in it (no location, say) keeps its line, with a dash for its value that a screen reader does
     not read out. Never display: none here: it takes the cell out of the table a screen reader is told about, and every
     later cell in the row is then read under the wrong column's name. */
  .table--stack td:empty::after {
    content: "-";
    content: "-"/"";
    color: var(--text-muted);
  }
}
/* @fileoverview The interview brief (P3-01): its questions, what to be ready for and the questions to ask, on the
   Interview tab and on the printable view; and the printable view's own page, plain on screen and black on white on
   US Letter paper when printed (the paper size is in _tokens.scss). */
.brief {
  max-width: var(--measure);
  margin-bottom: var(--space-6);
}

.brief__group {
  margin-top: var(--space-5);
}

.brief__list {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
}

.brief__item {
  margin-bottom: var(--space-4);
}

.brief__question {
  margin: 0 0 var(--space-1);
  font-weight: var(--weight-bold);
}

.brief__detail {
  margin: 0 0 var(--space-1);
}

.brief__label {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.brief__answers {
  margin: 0 0 var(--space-1);
  padding-left: var(--space-5);
}

.print-sheet {
  max-width: var(--page-width);
  margin: 0 auto;
  padding: var(--space-6) var(--space-4) var(--space-7);
}

@media print {
  .print-page {
    background: var(--print-paper);
    color: var(--print-ink);
    font-size: var(--print-text);
  }
  .print-page .muted,
  .print-page .lead,
  .print-page .brief__label {
    color: var(--print-ink);
  }
  .print-page h1 {
    font-size: var(--text-xl);
  }
  .print-page h2 {
    font-size: var(--text-lg);
  }
  .print-page h3 {
    font-size: var(--text-base);
  }
  .print-sheet,
  .print-page .brief {
    max-width: none;
    padding: 0;
  }
  .print-hint {
    display: none;
  }
  .print-page .brief__item {
    break-inside: avoid;
  }
  .print-page h2,
  .print-page .brief__group {
    break-after: avoid;
  }
}
/* @fileoverview The chat component (P3-03; the free chat and the profile interview reuse it), the practice part of
   the Interview tab, and the Coach's list of conversations (P4-01). A Copy reply button, which public/js/chat.js adds
   under each of the Coach's finished replies, sits in a wrapping row with the line that says whether it copied. The message list has no height or overflow of its own: the page scrolls, so every message can be
   scrolled back to and nothing is cut off, at any width (the old app's chat stopped scrolling after a CSS change;
   Ryan's 2024 whiteboard, R38). public/js/chat.js keeps the newest line in view as a reply arrives, unless the person
   has scrolled up to read. Do not give the list a max-height, an overflow or a fixed position without asking Ryan. */
.chat {
  max-width: var(--measure);
}

.chat__list {
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
}

.chat__message {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-bubble);
  /* An address ending in #latest opens with the newest message clear of the top edge. */
  scroll-margin-top: var(--space-4);
}

/* Bubbles, after the old app's messages: rounded, with the corner nearest the speaker's side left square. */
.chat__message--assistant {
  border-top-left-radius: var(--radius-sm);
  background: var(--surface-raised);
}

.chat__message--user {
  margin-left: var(--space-5);
  border-top-right-radius: var(--radius-sm);
  background: var(--surface);
}

.chat__who {
  margin: 0 0 var(--space-1);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

.chat__time {
  font-weight: var(--weight-normal);
}

.chat__body {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* What the person wrote, a reply still arriving (built by chat.js without data-rendered), and Markdown the libraries
   could not render keep their line breaks. A rendered reply is HTML and takes its breaks from its own elements. */
.chat__body--plain,
.chat__body:not([data-rendered]) {
  white-space: pre-wrap;
}

.chat__body > :last-child {
  margin-bottom: 0;
}

.chat__body ul,
.chat__body ol {
  padding-left: var(--space-5);
}

/* A code block or a table in a reply scrolls inside itself, so the page never scrolls sideways on a phone. */
.chat__body pre,
.chat__body table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

.chat__body pre {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
}

/* Code in a sentence and a quotation in a reply, as the old app's messages showed them. */
.chat__body :not(pre) > code {
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
}

.chat__body blockquote {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-3);
  border-left: var(--rule-width) solid var(--border);
  color: var(--text-muted);
  font-style: italic;
}

.chat__mark,
.chat__waiting {
  color: var(--danger);
  font-size: var(--text-sm);
}

.chat__mark {
  margin: var(--space-2) 0 0;
}

.chat__form {
  margin-bottom: var(--space-4);
}

.chat__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-3);
}

.chat__copied {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.coach__list {
  max-width: var(--measure);
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
}

.coach__item {
  margin-bottom: var(--space-2);
}

.coach__link {
  overflow-wrap: anywhere;
}

.practice {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: var(--border-width) solid var(--border);
}

.practice__sessions {
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
}

.practice__session {
  margin-bottom: var(--space-2);
}

/* @fileoverview The review of a practice session (P3-04), on the session's page and on the Interview tab: the form that
   asks for one, and the review itself, laid out compactly toward the plan's one-screen review: each point names an
   answer with the person's own words quoted on the same line, its parts and points sit close together, and a tighter
   version is a short block set off by a rule at its side, kept in its line breaks. The answer and story links keep
   their full-size targets (agent/ui-standards.md), so each of those lines is at least 44px tall, however short. Under
   "How you spoke" (P3-06), each spoken answer's figures sit beside its link as a quote does. */
.review-start {
  max-width: var(--measure);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--border-width) solid var(--border);
}

.review {
  max-width: var(--measure);
  margin: var(--space-5) 0 var(--space-6);
  overflow-wrap: anywhere;
}

/* The line under the heading saying which review it is, and "None" under a part, sit close to what follows. */
.review > .muted {
  margin-bottom: var(--space-2);
}

.review__overall {
  margin-bottom: var(--space-3);
  font-size: var(--text-lg);
}

/* The headings of the review's parts sit close to what they head. */
.review__part {
  margin: var(--space-3) 0 var(--space-1);
  font-size: var(--text-lg);
  line-height: var(--leading-tight);
}

.review__list {
  margin: 0;
  padding-left: var(--space-5);
}

/* Points sit close together: a linked answer's or story's line already has room above its words, from the link's
   full-size target. */
.review__item {
  margin-bottom: var(--space-1);
}

.review__answer {
  margin: 0;
  font-weight: var(--weight-bold);
}

.review__quote,
.review__figures {
  color: var(--text-muted);
  font-weight: var(--weight-normal);
}

.review__detail {
  margin: 0;
}

.review__label {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.review__tighter {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-2);
  border-left: var(--rule-width) solid var(--border);
  white-space: pre-wrap;
}

/* @fileoverview The story bank (P3-02): the list of stories on the Stories page, each a card with its state, the entry
   it is about, its themes as a wrapped row of tags and its four parts; the themes' boxes in a story's form; and each
   draft on the review page. */
.story-list {
  max-width: var(--measure);
  margin: 0;
  padding: 0;
  list-style: none;
}

.story {
  margin-bottom: var(--space-5);
  padding: var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  overflow-wrap: anywhere;
}

.story__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lg);
}

.story__meta {
  margin: 0 0 var(--space-2);
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.story__state {
  font-weight: var(--weight-bold);
}

.story__state--ready {
  color: var(--success);
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
}

.tags li {
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  font-size: var(--text-sm);
}

.story__parts {
  margin: 0 0 var(--space-3);
}

.story__parts dt {
  font-weight: var(--weight-bold);
}

.story__parts dd {
  margin: 0 0 var(--space-3);
}

/* The themes' boxes, two or more to a row where there is room. */
.choice__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--field-narrow), 1fr));
  gap: 0 var(--space-4);
}

.story-draft {
  max-width: var(--measure);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-4);
  border-bottom: var(--border-width) solid var(--border);
}

/* @fileoverview The profile interview (P4-02): each proposal's card under the reply that made it, on the page's own
   surface so it stands out from the reply's raised bubble: what it proposes (the bullet it would replace muted), a
   warning in the danger colour when it cannot be accepted as it stands, Accept and Decline in a wrapping row, and Edit, a
   disclosure drawn as a button (the summary is the control, so it gets the button's 44px) that opens the box and Save;
   once decided, the line that says how, in the success colour when the profile changed. A proposal the app could not use
   is a muted line. On the Profile page, "Interview me about this job" sits under the job's bullets. */
.proposal {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  overflow-wrap: anywhere;
  /* A decision opens the page at its card (an address ending in #proposal- and its id), clear of the top edge. */
  scroll-margin-top: var(--space-4);
}

.proposal__heading {
  margin: 0 0 var(--space-2);
  font-weight: var(--weight-bold);
}

.proposal__label {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.proposal__text {
  margin: 0 0 var(--space-3);
}

.proposal__text--old {
  color: var(--text-muted);
}

.proposal__warning {
  margin: 0 0 var(--space-3);
  color: var(--danger);
  font-size: var(--text-sm);
}

.proposal__decision {
  margin: 0 0 var(--space-2);
  font-weight: var(--weight-bold);
}

.proposal--accepted .proposal__decision,
.proposal--edited .proposal__decision {
  color: var(--success);
}

.proposal__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.proposal__actions form {
  margin: 0;
}

.proposal .form__note:empty {
  margin: 0;
}

/* A refused Accept, Decline or Save opens the page at the card's note (an address ending in #proposal- and its id,
   then -note), under the buttons and right above the Edit box, clear of the top edge, so the refusal is in view on a
   phone however long the card's bullets are. */
.proposal > .form__note {
  scroll-margin-top: var(--space-4);
}

.proposal__edit {
  margin-top: var(--space-2);
}

.proposal__edit > summary {
  list-style: none;
}

.proposal__edit > summary::-webkit-details-marker {
  display: none;
}

.proposal__edit > .form {
  margin-top: var(--space-3);
}

.proposal-unusable {
  margin: var(--space-3) 0 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.entry__interview {
  margin: 0 0 var(--space-4);
}

/* @fileoverview The practice session's voice level (P3-06): the sentence saying where his voice goes and the
   microphone's row under the answer box ("Speak your answer", "I'm done", the Listening mark, the offer to download the speech pack), the words still being recognized,
   greyed, the status line that says why speaking is off, the line under a spoken answer with its time and pace, and the
   reading-aloud controls below the conversation. Colours only through the tokens; the Listening mark is a still dot
   in the danger colour beside its word, so nothing moves and the word carries the meaning. */
.voice-mic {
  max-width: var(--measure);
  margin-bottom: var(--space-3);
}

.voice-mic__buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.voice-mic__listening {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  color: var(--danger);
  font-weight: var(--weight-bold);
}

.voice-mic__listening::before {
  content: "";
  width: var(--space-3);
  height: var(--space-3);
  border-radius: 50%;
  background: var(--danger);
}

/* Where his voice goes, above the microphone's buttons. */
.voice-mic__hint {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
}

/* Words still being recognized: greyed, and not a live region, so a screen reader is not read every guess. */
.voice-mic__interim {
  min-height: calc(var(--text-base) * var(--leading));
  margin: var(--space-2) 0 0;
  color: var(--text-muted);
  font-style: italic;
  overflow-wrap: anywhere;
}

.voice-note {
  max-width: var(--measure);
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
}

.voice-note:empty {
  margin: 0;
}

.chat__spoken {
  margin: var(--space-2) 0 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.voice {
  max-width: var(--measure);
  margin: var(--space-5) 0;
  padding: var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.voice h2 {
  margin-top: 0;
}

.voice .select {
  max-width: var(--field-min);
}

/* @fileoverview The practice session's video level (P3-07): the camera and recording panel below the conversation, a
   card like the reading-aloud one; the small picture of himself, in the camera's own shape, cropped rather than
   stretched, and turned as a mirror unless he turns that off; and the Recording mark, a still dot in the danger colour
   beside its word, so nothing moves and the word carries the meaning. Colours only through the tokens. */
.video {
  max-width: var(--measure);
  margin: var(--space-5) 0;
  padding: var(--space-4);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.video h2 {
  margin-top: 0;
}

.video__frame {
  width: 100%;
  max-width: var(--self-view-width);
  aspect-ratio: var(--self-view-ratio);
  margin-bottom: var(--space-3);
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}

.video__self {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video__self--mirror {
  transform: scaleX(-1);
}

.video__recording {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  color: var(--danger);
  font-weight: var(--weight-bold);
}

.video__recording::before {
  content: "";
  width: var(--space-3);
  height: var(--space-3);
  border-radius: 50%;
  background: var(--danger);
}

/* @fileoverview The Settings page's own parts (REPORT 4.1.6). The Color setting's swatch (D10, R84): each theme's page
   with its Coach's color as the dot, by day on the left and at night on the right, beside the choice's name. It shows
   each theme as it is, whatever the theme and scheme of the page around it, so its colors are the fixed
   --swatch-<theme>-<day|night> tokens, each equal to that theme's own role (styles/_tokens.scss). Decoration: the
   name carries the choice, and the swatch is aria-hidden. */
.color-swatch {
  display: inline-flex;
  flex: none;
  width: var(--swatch-width);
  height: var(--swatch-height);
  overflow: hidden;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 var(--border-width) var(--border-control);
}

.color-swatch__half {
  display: grid;
  flex: 1 1 0;
  place-items: center;
  background: var(--swatch-page);
}

.color-swatch__half::after {
  content: "";
  width: var(--swatch-dot);
  height: var(--swatch-dot);
  border-radius: 50%;
  background: var(--swatch-coach);
}

.color-swatch__half--slate-day {
  --swatch-page: var(--swatch-slate-day);
  --swatch-coach: var(--swatch-slate-day-coach);
}

.color-swatch__half--slate-night {
  --swatch-page: var(--swatch-slate-night);
  --swatch-coach: var(--swatch-slate-night-coach);
}

.color-swatch__half--violet-day {
  --swatch-page: var(--swatch-violet-day);
  --swatch-coach: var(--swatch-violet-day-coach);
}

.color-swatch__half--violet-night {
  --swatch-page: var(--swatch-violet-night);
  --swatch-coach: var(--swatch-violet-night-coach);
}
