/* LifeOS styles. Tokens live in design-tokens.css (v2, Linear-style); this file
   uses tokens only, never raw colours. Eight sections, one owner each
   (docs/redesign-spec.md §7.2): edit only your own section. */

/* == 1 base == */
:root {
  font-family: var(--font-sans);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color: var(--text-2);
  background: var(--bg-app);
}
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; background: var(--bg-app); color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
button, input, textarea, select { font: inherit; }
button, a, input, textarea, select { -webkit-tap-highlight-color: transparent; }
button { cursor: pointer; color: inherit; border: 0; }
button:disabled { opacity: .45; cursor: default; }
a { color: inherit; }
/* Hover appears at once and fades out over 150 ms. */
button, a, input, textarea, select { transition: border-color var(--dur-fade), color var(--dur-fade), background-color var(--dur-fade), opacity var(--dur-fade); }
:is(button, a, input, textarea, select):hover { transition-duration: 0s; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
::selection { background: var(--accent-soft); }
svg { display: block; flex-shrink: 0; }
h1, h2, h3, p { margin: 0; }
h1 { font-size: clamp(26px, 2.1vw, 32px); font-weight: var(--fw-semibold); line-height: 1.15; letter-spacing: var(--tr-title); color: var(--text-1); }
h2 { font-size: var(--fs-title); font-weight: var(--fw-semibold); line-height: 1.3; letter-spacing: var(--tr-title); color: var(--text-1); }
h3 { font-size: 14px; font-weight: var(--fw-medium); line-height: 1.5; color: var(--text-2); }
:lang(zh), [lang|="zh"] { font-family: var(--font-han); }
[hidden] { display: none !important; }
.spin svg { animation: spin 1.1s linear infinite; }
/* Every number: tabular, lining, never split from its unit. */
.num { font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.unit { color: var(--text-3); }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 50% { opacity: .5; } }
@keyframes enter { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@media (max-width: 700px) {
  body { font-size: var(--fs-regular); line-height: var(--lh-regular); }
  h1 { font-size: 26px; }
}
/* Touch: inputs ≥16 px (no iOS zoom). Hit areas are ≥44 px per component below. */
@media (pointer: coarse) {
  input, textarea, select { font-size: max(16px, 1em); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* == 2 components == */
/* Buttons (§1.6.3). A bare .button is neutral (secondary); .primary is the one indigo fill. */
.button { position: relative; display: inline-flex; justify-content: center; align-items: center; gap: 6px; min-height: var(--control-h); padding: 0 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-raised); color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); text-decoration: none; white-space: nowrap; }
.button svg { width: var(--icon-sm); height: var(--icon-sm); }
.button:hover { border-color: var(--line-strong); background-image: linear-gradient(var(--bg-hover), var(--bg-hover)); }
.button.primary { border-color: transparent; background: var(--accent); color: var(--on-accent); }
.button.primary:hover { background: var(--accent-hover); }
.button.ghost, .button.danger { border-color: transparent; background: transparent; color: var(--text-2); }
.button.ghost:hover { background: var(--bg-hover); color: var(--text-1); }
.button.danger { color: var(--danger); }
.button.danger:hover { background: var(--bg-hover); }
.button:disabled, .button[aria-disabled="true"] { opacity: 1; border-color: var(--line-subtle); background: transparent; color: var(--text-4); cursor: default; }
.button.wide { width: 100%; }
.icon-button { position: relative; display: grid; place-items: center; width: var(--control-h); height: var(--control-h); padding: 0; background: transparent; border: 1px solid transparent; border-radius: var(--r-sm); color: var(--text-3); }
.icon-button:hover { background: var(--bg-hover); color: var(--text-1); }
.icon-button svg { width: var(--icon); height: var(--icon); }
.icon-button:disabled { opacity: 1; background: transparent; color: var(--text-4); }
@media (pointer: coarse) {
  .icon-button { width: var(--hit-min); height: var(--hit-min); }
}

/* Inputs and the segmented control (§1.6.4). */
.input { width: 100%; min-height: var(--input-h); padding: 0 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-raised); color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
textarea.input { padding: 6px 10px; resize: vertical; }
.input::placeholder { color: var(--text-4); }
.input:focus-visible, .input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.input:disabled { color: var(--text-4); }
.segmented { display: inline-flex; align-items: center; gap: 2px; max-width: 100%; padding: 2px; border: 1px solid var(--line-subtle); border-radius: var(--r-md); background: var(--bg-hover); }
.segmented > button, .segmented > a, .segment { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 24px; padding: 0 10px; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); text-decoration: none; white-space: nowrap; }
.segmented > :is(button, a, .segment):hover { color: var(--text-1); }
.segmented > [aria-pressed="true"], .segmented > [aria-selected="true"], .segmented > [aria-current="page"] { background: var(--bg-elevated); color: var(--text-1); box-shadow: var(--shadow-low); }
@media (pointer: coarse) {
  .input { font-size: max(16px, 1em); }
  .segmented > :is(button, a, .segment)::before { content: ""; position: absolute; inset: -10px 0; }
}

/* Chips (§1.6.5). */
.chip { display: inline-flex; align-items: center; gap: 6px; min-height: 22px; padding: 0 8px; border: 1px solid var(--line); border-radius: var(--r-full); background: transparent; color: var(--text-2); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); white-space: nowrap; }
.chip svg { width: 12px; height: 12px; }
.chip.is-danger { border-color: var(--danger-line); background: var(--danger-soft); color: var(--danger); }
.chip.is-warn { border-color: var(--warn-line); background: var(--warn-soft); color: var(--warn); }
button.chip, a.chip { position: relative; cursor: pointer; text-decoration: none; }
button.chip:hover, a.chip:hover { background-color: var(--bg-hover); color: var(--text-1); }
.chip[aria-pressed="true"] { border-color: var(--line-strong); background: var(--bg-selected); color: var(--text-1); }
.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 20px; }
.chips.compact { margin: 0; }
@media (pointer: coarse) {
  button.chip::before, a.chip::before { content: ""; position: absolute; inset: -11px -2px; }
}

/* Signal marks (§1.6.6): aria-hidden, always followed by a visible word. */
.sig-danger, .sig-warn, .sig-unknown, .sig-now { display: inline-block; flex-shrink: 0; vertical-align: middle; }
.sig-danger { width: 6px; height: 6px; border-radius: 50%; background: var(--danger); }
.sig-warn { width: 7px; height: 7px; border: 1.5px solid var(--warn); border-radius: 50%; }
.sig-unknown { width: 7px; height: 7px; border: 1.5px dashed var(--text-3); border-radius: 50%; }
.sig-now { width: 2px; height: 12px; border-radius: 1px; background: var(--accent); }
/* Task status glyph: 14×14 inline SVG from statusGlyph(); not a button, never a checkbox. */
.st { display: block; flex-shrink: 0; width: 14px; height: 14px; }

/* List row (§1.6.7). A <button class="row"> never contains another button. */
.row { display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; align-items: start; column-gap: 10px; width: 100%; min-height: var(--row-h); padding: 8px 10px; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); text-align: left; text-decoration: none; }
.row:has(.row-why) { min-height: var(--row-h-2); }
.row > .st, .row > .row-mark { margin-top: 2px; }
.row-title { min-width: 0; overflow: hidden; color: var(--text-1); font-weight: var(--fw-medium); text-overflow: ellipsis; white-space: nowrap; }
.row-why { grid-column: 2 / 4; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: var(--why-lines, 2); line-clamp: var(--why-lines, 2); color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); overflow-wrap: anywhere; }
.row-meta { display: flex; align-items: center; gap: 8px; color: var(--text-3); font-size: var(--fs-mini); white-space: nowrap; }
a.row, button.row { cursor: pointer; }
a.row:hover, button.row:hover { background: var(--bg-hover); }
.row:focus-visible { outline: none; background: var(--bg-selected); box-shadow: inset 0 0 0 1px var(--accent-border); }
.row-list { container: rows / inline-size; display: flex; flex-direction: column; }
/* The epic: a chip on the right when the list is wide, its own line under the title when narrow (phones). */
.row-epicline { display: none; grid-column: 2 / -1; grid-row: 2; align-items: center; gap: 4px; min-width: 0; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.row-epicline > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-epicline svg { width: 11px; height: 11px; flex-shrink: 0; }
@container rows (max-width: 419px) { .row-epic { display: none; } .row-epicline { display: flex; } }
.group-head { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 30px; padding: 0 10px; border: 0; border-radius: var(--r-sm); background: var(--bg-group); color: var(--text-2); font-size: var(--fs-mini); font-weight: var(--fw-semibold); line-height: var(--lh-mini); text-align: left; }
.group-head .group-count { color: var(--text-3); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.group-head .chev { margin-left: auto; color: var(--text-3); transition: transform var(--dur-quick); }
.group-head[aria-expanded="true"] .chev { transform: rotate(90deg); }
button.group-head:hover { color: var(--text-1); }
@media (max-width: 700px) {
  .row { min-height: 44px; font-size: var(--fs-regular); line-height: 20px; }
  .row:has(.row-why) { min-height: 56px; }
  .row > .st, .row > .row-mark { margin-top: 3px; }
  .row-why { font-size: var(--fs-small); line-height: var(--lh-small); }
  .group-head { min-height: 36px; font-size: var(--fs-mini); }
}

/* Widget card (§1.6.8). */
.w { position: relative; display: flex; flex-direction: column; gap: 8px; height: 100%; min-width: 0; padding: var(--widget-pad); overflow: hidden; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); color: var(--text-2); text-align: left; }
a.w, button.w { width: 100%; font: inherit; text-decoration: none; cursor: pointer; }
a.w:hover, button.w:hover { border-color: var(--line); background: var(--bg-raised); }
.w-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 16px; color: var(--text-3); font-size: var(--fs-mini); line-height: 16px; }
.w-label, .w-head :is(h2, h3) { display: flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: 16px; letter-spacing: 0; text-overflow: ellipsis; white-space: nowrap; }
.w-head svg { width: var(--icon-sm); height: var(--icon-sm); }
.w-aside { flex-shrink: 0; color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.w-aside.is-accent { color: var(--accent-text); }
.w-body { flex: 1; min-height: 0; }
.w-foot { display: flex; align-items: center; gap: 6px; min-height: 16px; margin-top: auto; color: var(--text-3); font-size: var(--fs-mini); line-height: 16px; }
.w-metric { color: var(--text-1); font-size: var(--fs-metric); font-weight: var(--fw-medium); line-height: var(--lh-metric); letter-spacing: var(--tr-metric); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.w-metric small, .w-metric .unit { color: var(--text-3); font-size: var(--fs-small); font-weight: var(--fw-regular); letter-spacing: 0; }
.w-metric.is-dim { color: var(--text-2); }

/* Skeletons (§1.6.10): shimmer ≤1.2 s, off under reduced motion and under an error. */
.skeleton { display: block; border-radius: var(--r-sm); background-color: var(--bg-raised); background-image: linear-gradient(90deg, transparent 0, var(--bg-hover) 50%, transparent 100%); background-size: 200% 100%; animation: shimmer 1.2s linear infinite; }
.skeleton.is-static, .is-error .skeleton { animation: none; background-image: none; }

/* Progress (§1.6.11): a 4 px neutral track; width via data-width + JS. Never coloured. */
.progress-track { display: flex; height: 4px; overflow: hidden; border-radius: var(--r-full); background: var(--bg-selected); }
.progress-track span { display: block; height: 100%; border-radius: var(--r-full); background: var(--text-2); }

/* Toast (§1.6.13): one slot, bottom-right on desktop, above the tab bar on phones. */
#toast { position: fixed; z-index: var(--z-toast); right: 20px; bottom: 20px; display: flex; align-items: center; gap: 12px; max-width: 440px; padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-elevated); box-shadow: var(--shadow-medium); color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); pointer-events: none; opacity: 0; transform: translateY(8px); transition: opacity var(--dur-fade), transform var(--dur-fade); }
#toast.visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
#toast .button { flex-shrink: 0; }
@media (max-width: 700px) {
  #toast { left: max(12px, env(safe-area-inset-left)); right: max(12px, env(safe-area-inset-right)); bottom: calc(var(--tabbar-h) + var(--tabbar-bottom) + 8px); max-width: none; }
}

/* Accessibility helpers. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.table-scroll { max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
.table-scroll > table { min-width: 100%; border-collapse: collapse; }

/* Empty state (§1.6.10, empty()): an icon, a bold line and one sentence. */
.empty { padding: 16px 0; color: var(--text-3); font-size: var(--fs-small); line-height: 1.6; }
.empty svg { margin-bottom: 12px; color: var(--text-3); }
.empty strong { display: block; margin-bottom: 4px; color: var(--text-2); font-size: 14px; font-weight: var(--fw-medium); }
/* Boot spinner (index.html, retry-boot). */
.loader { width: 16px; height: 16px; border: 1.5px solid var(--line); border-top-color: var(--text-3); border-radius: var(--r-full); animation: spin .8s linear infinite; }

/* == 3 shell == */
/* Frame (§1.6.1): sidebar + inset panel on desktop; the document scrolls (the board's drag autoscroll needs it). */
html:has(> body > #app > .shell), body:has(> #app > .shell) { background: var(--bg-sidebar); }
.shell { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; min-height: 100dvh; }
.sidebar { position: sticky; top: 0; display: flex; flex-direction: column; gap: 12px; height: 100vh; height: 100dvh; padding: 10px 8px 12px; overflow-y: auto; }
.brand { display: flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 8px; color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-semibold); line-height: var(--lh-small); }
.logo-mark { width: 32px; height: 32px; display: grid; grid-template-columns: repeat(2, 5px); grid-template-rows: repeat(2, 5px); gap: 4px; place-content: center; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-card); }
.logo-mark i { background: var(--text-1); border-radius: var(--r-full); }
.logo-mark i:nth-child(2), .logo-mark i:nth-child(3) { opacity: .42; }
.logo-mark i:last-child { opacity: .62; }
.brand .logo-mark { width: 28px; height: 28px; grid-template-columns: repeat(2, 4px); grid-template-rows: repeat(2, 4px); gap: 4px; }
.nav { display: flex; flex-direction: column; gap: 1px; }
.nav-item { position: relative; display: flex; align-items: center; gap: 8px; min-height: 28px; padding: 0 8px; border-radius: var(--r-md); color: var(--text-2); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); text-decoration: none; white-space: nowrap; }
.nav-item svg { width: var(--icon); height: var(--icon); color: var(--text-3); }
.nav-item:hover { background: var(--bg-hover); color: var(--text-1); }
.nav-item[aria-current="page"] { background: var(--bg-selected); color: var(--text-1); }
.nav-item[aria-current="page"] svg { color: var(--text-2); }
.nav-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.nav-count { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; color: var(--text-3); font-size: var(--fs-micro); font-weight: var(--fw-medium); line-height: var(--lh-micro); font-variant-numeric: tabular-nums; }
.nav-count:empty { display: none; }
.sidebar-foot { display: flex; flex-direction: column; gap: 2px; margin-top: auto; }
.sync-row { display: flex; align-items: center; gap: 8px; min-height: 28px; padding: 4px 8px; border-radius: var(--r-md); color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); text-decoration: none; }
.sync-row:hover { background: var(--bg-hover); color: var(--text-2); }
.sync-row:empty { display: none; }
.panel { min-width: 0; min-height: calc(100dvh - 2 * var(--panel-inset)); margin: var(--panel-inset) var(--panel-inset) var(--panel-inset) 0; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-app); }

/* View header (§1.6.1): icon + h1 + context on the left; freshness chip, refresh and view actions on the right. */
.view-header { position: sticky; top: 0; z-index: var(--z-header); display: flex; align-items: center; justify-content: space-between; gap: 12px; height: var(--header-h); padding: 0 12px 0 var(--content-pad); border-bottom: 1px solid var(--line-subtle); border-radius: var(--r-lg) var(--r-lg) 0 0; background: var(--bg-app); }
/* The title block fills what the actions leave, but never less than icon + h1: only the context ellipsizes. */
.vh-title { display: flex; flex: 1 1 auto; align-items: center; gap: 8px; min-width: min-content; }
.view-header h1 { flex-shrink: 0; }
.vh-icon { display: grid; place-items: center; color: var(--text-3); }
.vh-icon svg { width: var(--icon); height: var(--icon); }
.view-header h1 { margin: 0; color: var(--text-1); font-size: 15px; font-weight: var(--fw-semibold); line-height: 20px; letter-spacing: 0; white-space: nowrap; }
.vh-context { display: flex; flex: 1 1 0; align-items: center; gap: 6px; width: 0; min-width: 0; overflow: hidden; color: var(--text-3); font-size: var(--fs-small); line-height: var(--lh-small); text-overflow: ellipsis; white-space: nowrap; }
.vh-context:empty { display: none; }
.vh-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.vh-fresh:empty, .vh-view-actions:empty { display: none; }
.vh-view-actions, .view-actions { display: flex; align-items: center; gap: 8px; }
.view > .view-actions { justify-content: flex-end; flex-wrap: wrap; margin-bottom: 16px; }
.fresh-chip { text-decoration: none; }
.fresh-chip.is-offline { color: var(--text-2); }
.view { width: 100%; max-width: var(--content-max); margin: 0 auto; padding: var(--content-pad); }
.view.is-stale .w-metric { color: var(--text-2); }

/* Phone tab bar and «Ещё» (§1.6.2); hidden on desktop. */
.tabbar, .edit-toolbar { display: none; }
.tab { position: relative; display: flex; flex: 1; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 0; height: 100%; padding: 0 2px; border: 0; border-radius: var(--r-full); background: transparent; color: var(--text-3); font-size: var(--fs-micro); font-weight: var(--fw-medium); line-height: var(--lh-micro); text-decoration: none; }
.tab svg { width: 22px; height: 22px; }
.tab[aria-current="page"] { background: var(--bg-selected); color: var(--text-1); }
.tab-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.more-list { display: flex; flex-direction: column; padding-bottom: 8px; }
.more-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 12px; border-radius: var(--r-md); color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); text-decoration: none; }
.more-row svg { width: 20px; height: 20px; color: var(--text-3); }
.more-row:hover { background: var(--bg-hover); }
.more-row[aria-current="page"] { background: var(--bg-selected); }
.more-row .nav-count { font-size: var(--fs-mini); line-height: var(--lh-mini); }

/* Sheet (§1.6.12): the frame only; content styles belong to the package that fills it. */
dialog.sheet { position: fixed; z-index: var(--z-sheet); max-width: none; max-height: none; margin: 0; padding: 0; overflow: hidden; border: 0; background: var(--bg-elevated); box-shadow: var(--shadow-high); color: var(--text-2); }
dialog.sheet::backdrop { background: var(--scrim); }
dialog.sheet.is-side { inset: 0 0 0 auto; width: min(440px, 100vw); height: 100vh; height: 100dvh; border-left: 1px solid var(--line); animation: sheet-side var(--dur-regular) var(--ease-out); }
dialog.sheet.is-bottom { inset: auto 0 0 0; width: 100%; max-height: 88vh; max-height: 88dvh; border-top: 1px solid var(--line); border-radius: var(--r-xl) var(--r-xl) 0 0; animation: sheet-up var(--dur-regular) var(--ease-out); }
.sheet-inner { display: flex; flex-direction: column; height: 100%; max-height: inherit; }
dialog.sheet.is-bottom .sheet-inner { max-height: 88vh; max-height: 88dvh; padding-bottom: env(safe-area-inset-bottom); }
.sheet-grab { display: none; flex-shrink: 0; width: 36px; height: 4px; margin: 8px auto 0; border-radius: var(--r-full); background: var(--line-strong); }
dialog.sheet.is-bottom .sheet-grab { display: block; }
.sheet-head { display: flex; flex-shrink: 0; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; padding: 8px 12px 8px 20px; }
.sheet-title { min-width: 0; overflow: hidden; color: var(--text-1); font-size: var(--fs-title); font-weight: var(--fw-semibold); line-height: var(--lh-title); letter-spacing: var(--tr-title); text-overflow: ellipsis; white-space: nowrap; }
dialog.sheet.is-bottom .sheet-title { font-size: var(--fs-large); line-height: var(--lh-large); letter-spacing: 0; }
.sheet-body { flex: 1; min-height: 0; padding: 4px 20px 20px; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
dialog.sheet.is-bottom .sheet-body { padding: 4px 12px 12px; }
html.sheet-open { overflow: hidden; }
@keyframes sheet-up { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes sheet-side { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (pointer: coarse) { .sheet-close::before { content: ""; position: absolute; inset: -8px; } }

/* Data states (§5.1, §5.2): banners above content, one card instead of content, the status footer, skeletons. */
.state-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-bottom: 16px; padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-card); color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.state-banner-text { flex: 1 1 220px; min-width: 0; }
.state-banner-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin-left: auto; }
.link-button { position: relative; display: inline-flex; align-items: center; padding: 0; border: 0; background: none; color: var(--accent-text); font-size: inherit; font-weight: var(--fw-medium); line-height: inherit; text-decoration: none; cursor: pointer; }
.link-button:hover { text-decoration: underline; }
@media (pointer: coarse) { .link-button::before { content: ""; position: absolute; inset: -12px -6px; } }
.state-card { max-width: 560px; margin: 32px auto; padding: 20px; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); }
.state-card h2 { display: flex; align-items: center; gap: 8px; color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); letter-spacing: 0; }
.state-card p { margin-top: 6px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); overflow-wrap: anywhere; }
.state-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 16px; }
.state-actions:empty { display: none; }
.state-note { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.section-foot { display: flex; align-items: center; gap: 6px; min-width: 0; margin: 0; color: var(--text-3); font-size: var(--fs-mini); line-height: 16px; }
.section-foot-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.section-foot .link-button { margin-left: 2px; }
.skel-list { display: flex; flex-direction: column; gap: 2px; padding: 4px 0; }
.skel-row { display: grid; grid-template-columns: 16px minmax(0, 1fr); align-items: center; gap: 10px; min-height: var(--row-h); padding: 0 10px; }
.skel-dot { width: 14px; height: 14px; border-radius: var(--r-full); }
.skel-line { width: 70%; height: 12px; }
.skel-row:nth-child(2n) .skel-line { width: 52%; }
.skel-row:nth-child(3n) .skel-line { width: 84%; }

/* Boot (§5.2): logo and a spinner; after 8 s «Сервер отвечает медленно · Повторить». */
.boot { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-height: 100vh; min-height: 100dvh; color: var(--text-1); font-size: var(--fs-large); font-weight: var(--fw-semibold); line-height: var(--lh-large); }
.boot-note { color: var(--text-2); font-size: var(--fs-small); font-weight: var(--fw-regular); line-height: var(--lh-small); }

@media (max-width: 1000px) {
  .shell { grid-template-columns: 196px minmax(0, 1fr); }
}
/* Phone frame (§1.6.2). */
@media (max-width: 700px) {
  html:has(> body > #app > .shell), body:has(> #app > .shell) { background: var(--bg-app); }
  .shell { display: block; }
  .sidebar { display: none; }
  .panel { min-height: 100vh; min-height: 100dvh; margin: 0; border: 0; border-radius: 0; }
  .view-header { height: var(--header-h); padding: env(safe-area-inset-top) max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); border-bottom-color: transparent; border-radius: 0; }
  .view-header.is-scrolled { border-bottom-color: var(--line-subtle); }
  .view-header h1 { font-size: var(--fs-large); line-height: var(--lh-large); }
  .vh-icon { display: none; }
  .vh-context { font-size: var(--fs-mini); line-height: var(--lh-mini); }
  .vh-actions { gap: 4px; }
  .fresh-pre { display: none; }
  .view { padding: 12px max(16px, env(safe-area-inset-right)) calc(80px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
  .tabbar, .edit-toolbar { position: fixed; z-index: var(--z-tabbar); left: max(12px, env(safe-area-inset-left)); right: max(12px, env(safe-area-inset-right)); bottom: var(--tabbar-bottom); display: flex; align-items: stretch; gap: 2px; height: var(--tabbar-h); padding: 4px; border: 1px solid var(--line); border-radius: var(--r-full); background: var(--bg-bar); box-shadow: var(--shadow-medium); -webkit-backdrop-filter: var(--bar-blur); backdrop-filter: var(--bar-blur); }
  .edit-toolbar { align-items: center; justify-content: space-between; padding: 0 8px; }
  .edit-toolbar:empty { display: none; }
  .shell.is-editing:has(.edit-toolbar:not(:empty)) .tabbar { display: none; }
  .state-card { margin: 16px 0; padding: 16px; }
  .state-banner { font-size: var(--fs-small); }
}

/* == 4 board == */
/* Widget board (§2): square cells. JS writes --cols, --cell and each widget's grid-area from the board's
   own width; before that the spans below place widgets in the same order (grid-auto-flow: row only). */
.board-wrap { position: relative; }
.board { --cols: 4; --cell: 80px; position: relative; display: grid; grid-template-columns: repeat(var(--cols), var(--cell)); grid-auto-rows: var(--cell); grid-auto-flow: row; gap: var(--widget-gap); justify-content: start; }
.board[data-cols="8"] { --cols: 8; }
.board[data-cols="12"] { --cols: 12; }
/* The loading skeleton is never mounted: its cell comes from the container width alone. */
.board-wrap.is-skeleton { container-type: inline-size; }
.board-wrap.is-skeleton .board { --cell: min(100px, calc((100cqw - (var(--cols) - 1) * var(--widget-gap)) / var(--cols))); }
.board-wrap.is-skeleton .w-slot { border-radius: var(--r-lg); }
.w-slot.w-s { grid-column: span 2; grid-row: span 2; }
.w-slot.w-m { grid-column: span 4; grid-row: span 2; }
.w-slot.w-l { grid-column: span 4; grid-row: span 4; }

/* A slot is the fixed box; the widget card fills it and never sets its height (§2.4). */
.w-slot { position: relative; min-width: 0; min-height: 0; border-radius: var(--r-lg); }
.w-slot-body { height: 100%; }
.w-slot > .w-slot-body > * { height: 100%; min-height: 0; max-height: 100%; margin: 0; overflow: hidden; }
.w-slot.clipped .w-slot-body > * { -webkit-mask-image: linear-gradient(to bottom, var(--bg-card) calc(100% - 28px), transparent); mask-image: linear-gradient(to bottom, var(--bg-card) calc(100% - 28px), transparent); }
.w-failed { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
/* Touch hygiene (§2.5): no text selection or link callout on a long-press, only on the board. */
.board .w-slot { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.w-slot:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.w-slot.is-new .w-slot-body > * { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Edit mode: dashed outline, inert contents at .6, no wobble. */
.board.is-editing .w-slot { cursor: grab; }
.board.is-editing .w-slot-body { pointer-events: none; }
.board.is-editing .w-slot-body > * { border-style: dashed; border-color: var(--line-strong); }
.board.is-editing .w-slot-body > * > * { opacity: .6; }
/* «−» badge: 22 px, 6 px outside the top-left corner; its 44×44 hit area spans −12…32 px from the
   card's corner, so it never reaches past the 12 px gap into a neighbour. */
.w-badge { position: absolute; z-index: 3; top: -6px; left: -6px; display: none; place-items: center; width: 22px; height: 22px; padding: 0; border: 1px solid var(--line); border-radius: var(--r-full); background: var(--bg-elevated); color: var(--text-1); box-shadow: var(--shadow-low); }
.w-badge::before { content: ""; position: absolute; top: -7px; left: -7px; width: 44px; height: 44px; }
.w-badge:hover { background: var(--bg-raised); }
.board.is-editing .w-badge { display: grid; }
/* Corner resize handle (P1, RESIZE_HANDLE): a quarter arc; the 44×44 hit area stays inside the card. */
.w-resize { position: absolute; z-index: 3; right: 0; bottom: 0; display: none; width: 44px; height: 44px; touch-action: none; cursor: nwse-resize; }
.w-resize::after { content: ""; position: absolute; right: 5px; bottom: 5px; width: 16px; height: 16px; border-right: 2.5px solid var(--text-2); border-bottom: 2.5px solid var(--text-2); border-bottom-right-radius: 12px; }
.board.is-editing .w-resize { display: block; }
.w-slot.is-resizing .w-slot-body > * { border-color: var(--accent-border); }
.resize-frame { position: absolute; z-index: 15; display: flex; align-items: flex-start; padding: 8px; border: 1.5px dashed var(--accent-border); border-radius: var(--r-lg); pointer-events: none; }
.resize-label { padding: 2px 8px; border: 1px solid var(--line); border-radius: var(--r-full); background: var(--bg-elevated); color: var(--text-1); font-size: var(--fs-mini); line-height: var(--lh-mini); white-space: nowrap; box-shadow: var(--shadow-low); }

/* Drag: the lifted widget floats above the grid; a dashed slot marks where it lands. */
.w-slot.is-lifted { position: absolute; z-index: 20; transform: scale(1.02); cursor: grabbing; pointer-events: none; }
.w-slot.is-lifted .w-slot-body > * { border-style: solid; box-shadow: var(--lift); }
.w-slot.is-lifted .w-slot-body > * > * { opacity: 1; }
.w-slot.is-lifted :is(.w-badge, .w-resize) { display: none; }
.w-drop { border: 1px dashed var(--line-strong); border-radius: var(--r-lg); background: var(--bg-hover); pointer-events: none; }
html.is-board-dragging { -webkit-user-select: none; user-select: none; }

/* Size menu: a popover on fine pointers (and coarse ones above 700 px); the same rows in the bottom sheet. */
.w-popover { position: fixed; z-index: var(--z-menu); min-width: 216px; padding: 4px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-elevated); box-shadow: var(--shadow-medium); animation: w-pop var(--dur-fade) var(--ease-out); }
@keyframes w-pop { from { opacity: 0; transform: translateY(-4px); } }
.w-menu-list { display: flex; flex-direction: column; }
.w-menu-row { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 32px; padding: 0 8px; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); text-align: left; }
.w-menu-row:hover:not(:disabled), .w-menu-row:focus-visible { outline: none; background: var(--bg-hover); }
.w-menu-row:disabled { opacity: 1; color: var(--text-4); }
.w-menu-row.is-remove { color: var(--danger); }
.w-menu-row.is-remove svg { width: 20px; }
.w-menu-text { flex: 1; min-width: 0; }
.w-menu-check { display: grid; place-items: center; width: 14px; color: var(--accent-text); }
.w-menu-sep { height: 1px; margin: 4px 0; background: var(--line-subtle); }
.w-popover.is-coarse .w-menu-row, #sheet .w-menu-row { min-height: 44px; font-size: var(--fs-regular); line-height: var(--lh-regular); }
.w-glyph rect.on { fill: currentColor; }
.w-glyph rect.off { fill: none; stroke: currentColor; stroke-width: .8; opacity: .4; }

/* Widget gallery («+ Виджет») and the reset confirm. */
.w-gallery { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.w-gallery-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line-subtle); }
.w-gallery-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.w-gallery-title { color: var(--text-1); font-weight: var(--fw-medium); }
.w-gallery-desc { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.w-gallery-sizes { display: flex; flex-shrink: 0; gap: 6px; }
.w-size-chip { gap: 4px; min-height: 28px; padding: 0 10px; }
.w-size-chip .w-glyph { width: 14px; height: 14px; }
.w-gallery-empty { padding: 12px 0; color: var(--text-2); }
.w-gallery-foot { margin-top: 16px; }
.w-confirm-text { color: var(--text-2); }
.w-confirm-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }

/* Empty board (§2.5). */
.board.is-empty { display: block; }
.board-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-height: 200px; padding: 24px; border: 1px dashed var(--line-strong); border-radius: var(--r-lg); text-align: center; }
.board-empty-title { color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); }
.board-empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }

/* Phone: the header keeps only a 44 px «Виджеты» icon button; in edit mode «+ Виджет», «Сбросить» and
   «Готово» live in the edit toolbar that replaces the tab bar (one «Готово», in thumb reach). */
@media (max-width: 700px) {
  .board-action.is-extra { display: none; }
  .board-action[data-action="edit-widgets"] { width: var(--hit-min); min-height: var(--hit-min); padding: 0; }
  .board-action[data-action="edit-widgets"] svg { width: var(--icon); height: var(--icon); }
  .board-action-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
  .edit-toolbar .button { flex: 1; min-height: 44px; }
}

/* == 5 widgets == */
/* Overview widget contents (§2.8, WP6). Every height here is one that stack() / bodyRoom() in app.js budget with:
   secondary line 12/16 (13/18 on phones), title 13/18 (15/20), metric 32, state word 26, bar 8, button = --control-h
   (28, 40 on coarse pointers), gap 4. Change one side and the other together, or widgets clip (.clipped). */
.w-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.w-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 16px; }
.w-cols > * { min-width: 0; }
.w-main-link { position: relative; color: inherit; text-decoration: none; border-radius: var(--r-sm); }
.w-main-link:hover .w-metric, .w-main-link:hover .w-state { color: var(--text-1); }
.w-side { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.w-line { min-width: 0; margin: 0; overflow: hidden; color: var(--text-2); font-size: var(--fs-mini); line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
.w-line.is-2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; white-space: normal; overflow-wrap: anywhere; }
.w-line.is-quiet { color: var(--text-3); }
.w-line .sig-danger, .w-line .sig-warn, .w-line .sig-unknown, .w-line .sig-now, .w-state .sig-warn, .w-state .sig-now, .w-state .sig-unknown { margin-right: 6px; vertical-align: 1px; }
.w-line svg { display: inline-block; width: 12px; height: 12px; margin-right: 4px; vertical-align: -1px; color: var(--text-3); }
.w-line .is-accent { color: var(--accent-text); }
.w-line .num, .w-title.num { font-variant-numeric: tabular-nums; }
.w-title { min-width: 0; margin: 0; overflow: hidden; color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: 18px; text-overflow: ellipsis; white-space: nowrap; }
.w-title.is-2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; white-space: normal; overflow-wrap: anywhere; }
.w-state { display: flex; align-items: center; min-width: 0; margin: 0; color: var(--text-1); font-size: var(--fs-title); font-weight: var(--fw-medium); line-height: 26px; letter-spacing: -0.01em; white-space: nowrap; }
.w-state > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.w-state.is-dim { color: var(--text-2); }
.w-bar { display: block; padding-top: 4px; }
.w-actions { display: flex; margin-top: auto; }
.w-actions .button { max-width: 100%; }
.w-foot-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.w-label-more { color: var(--text-3); font-weight: var(--fw-regular); }
/* A long aside (the nutrition goal) gives way to the label instead of widening the card. */
.nutrition-w .w-label { flex-shrink: 0; }
.nutrition-w .w-aside { flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Key–value rows: macros (Питание M), supplies (Запасы M). */
.w-kv { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; margin: 0; font-size: var(--fs-mini); line-height: 16px; }
.w-kv-k { min-width: 0; overflow: hidden; color: var(--text-2); text-overflow: ellipsis; white-space: nowrap; }
.w-kv-v { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; color: var(--text-1); font-variant-numeric: tabular-nums; white-space: nowrap; }
.w-kv-v.is-warn { color: var(--warn); }
.w-kvlist { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.w-kv.is-row { height: 22px; border-bottom: 1px solid var(--line-subtle); }
.w-kv.is-row:last-child { border-bottom: 0; }
.w-macros, .w-macro { display: flex; flex-direction: column; gap: 4px; }
.w-macro .w-bar { padding: 0; }
.w-act { display: flex; flex-direction: column; min-width: 0; }
/* Альфред M: a composer stub that only opens the chat. */
.al-compose { position: relative; display: flex; align-items: center; width: 100%; min-height: var(--control-h); padding: 0 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-raised); color: var(--text-3); font-size: var(--fs-mini); text-align: left; cursor: text; }
.al-compose:hover { border-color: var(--line-strong); color: var(--text-2); }
/* Дальше L: the rest of today. Rows 28 px (30 on phones), the now-row 16, «завтра …» pinned to the bottom. */
.nx-body { display: flex; flex-direction: column; }
.nx-list { display: flex; flex-direction: column; margin: 0 -6px; }
.nx-row { display: grid; grid-template-columns: 38px 14px minmax(0, 1fr) auto; align-items: center; column-gap: 8px; width: auto; height: 28px; padding: 0 6px; border: 0; border-radius: var(--r-sm); background: none; color: var(--text-1); font: inherit; font-size: var(--fs-small); line-height: 18px; text-align: left; }
button.nx-row { cursor: pointer; }
button.nx-row:hover { background: var(--bg-hover); }
.nx-time { color: var(--text-3); font-size: var(--fs-mini); font-variant-numeric: tabular-nums; }
.nx-row.is-now .nx-time { color: var(--accent-text); }
.nx-bar { justify-self: center; width: 2px; height: 14px; border-radius: 1px; background: var(--line-strong); }
.nx-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-meta { display: inline-flex; align-items: center; gap: 6px; color: var(--text-3); font-size: var(--fs-mini); font-variant-numeric: tabular-nums; white-space: nowrap; }
.nx-meta.is-accent { color: var(--accent-text); }
.nx-now { position: relative; display: flex; align-items: center; height: 16px; margin: 0 6px; }
.nx-now::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--accent); }
.nx-now span { position: relative; padding-right: 6px; background: var(--bg-card); color: var(--accent-text); font-size: var(--fs-micro); line-height: 14px; font-variant-numeric: tabular-nums; }
.nx-more { height: 16px; margin: 0 6px; color: var(--text-3); font-size: var(--fs-mini); line-height: 16px; }
.nx-later { flex-shrink: 0; height: 28px; margin: auto 0 0; overflow: hidden; border-top: 1px solid var(--line-subtle); color: var(--text-3); font-size: var(--fs-mini); line-height: 27px; text-overflow: ellipsis; white-space: nowrap; }
/* Эпики: name · сегодня · просрочено · открыто. The head's column labels use the same widths as the rows. */
.epics-w { --ep-a: 48px; --ep-b: 68px; --ep-c: 50px; }
.ep-cols { display: grid; grid-template-columns: var(--ep-a) var(--ep-b) var(--ep-c); column-gap: 8px; text-align: right; }
.ep-list { display: flex; flex-direction: column; margin: 0 -6px; }
.ep-row { display: grid; grid-template-columns: minmax(0, 1fr) var(--ep-a) var(--ep-b) var(--ep-c); align-items: center; column-gap: 8px; height: 28px; padding: 0 6px; border-radius: var(--r-sm); color: var(--text-1); font-size: var(--fs-small); line-height: 18px; text-decoration: none; }
.ep-row:hover { background: var(--bg-hover); }
.ep-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ep-row .ep-c { display: inline-flex; align-items: center; justify-content: flex-end; gap: 5px; font-variant-numeric: tabular-nums; }
.ep-c.is-zero { color: var(--text-3); }
.ep-c.is-danger { color: var(--danger); }
.epics-w.is-l .ep-row { grid-template-rows: 18px 16px; row-gap: 2px; height: 46px; padding-top: 5px; padding-bottom: 5px; }
.ep-next { grid-column: 1 / -1; min-width: 0; overflow: hidden; color: var(--text-3); font-size: var(--fs-mini); line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
/* Attention strip (§4.2): exceptions only; one line on desktop, a horizontal scroller on phones. */
.attention { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; overflow-x: auto; scrollbar-width: none; }
.attention::-webkit-scrollbar { display: none; }
.att-chip { flex-shrink: 0; max-width: min(280px, 78vw); min-height: 24px; }
.att-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-tail { flex-shrink: 0; white-space: nowrap; }
.att-chip.is-unknown { color: var(--text-2); }
.att-more { color: var(--text-3); font-variant-numeric: tabular-nums; }
@media (pointer: coarse) {
  /* The chips' 44 px hit areas (::before) must not be clipped by the scroller. */
  .attention { margin: -10px 0 2px; padding: 10px 0; }
  .ep-row::before, .w-main-link::before { content: none; }
}
@media (max-width: 700px) {
  .w-line, .w-kv { font-size: var(--fs-small); line-height: 18px; }
  .w-title { font-size: var(--fs-regular); line-height: 20px; }
  .w-kv.is-row { height: 24px; }
  .nx-row { height: 30px; font-size: var(--fs-regular); line-height: 20px; }
  .nx-later { height: 30px; line-height: 29px; font-size: var(--fs-small); }
  .ep-row { height: 36px; font-size: var(--fs-regular); line-height: 20px; }
  .epics-w.is-l .ep-row { grid-template-rows: 20px 18px; height: 50px; }
  .ep-next { font-size: var(--fs-small); line-height: 18px; }
  .epics-w { --ep-a: 52px; --ep-b: 72px; --ep-c: 56px; }
  .ep-cols { font-size: var(--fs-mini); }
}
/* == 5a today == */
/* «Сегодня» widget (§3.5). Row heights stay at or under the G4 budgets that fitRows() in widgets.js uses:
   M 46 / 50 px (6 px padding, title + 1-line why), L 64 / 70 px ≤ 66 / 72 (title + 2-line why). */
.today-w .w-head .is-danger { color: var(--danger); }
.today-w .w-body { display: flex; flex-direction: column; min-width: 0; }
.today-w.is-s .w-body, .today-w.is-down .w-body { gap: 4px; }
.today-line { display: flex; align-items: center; gap: 6px; min-width: 0; color: var(--text-2); font-size: var(--fs-mini); line-height: 16px; }
.today-line > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.today-line .is-danger { color: var(--danger); }
.today-line .is-accent { color: var(--accent-text); }
.today-line .link-button { flex-shrink: 0; }
.today-s-title { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; color: var(--text-1); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: 16px; overflow-wrap: anywhere; }
.today-rows { margin: 0 -8px; }
.today-w .row, .today-w .row:has(.row-why) { min-height: 0; padding: 6px 8px; column-gap: 8px; }
.today-w .row > .st, .today-w .row > .row-mark { margin-top: 2px; }
.today-w.is-m .row { --why-lines: 1; }
.today-w.is-l .row { --why-lines: 2; row-gap: 2px; }
.today-w .row-why { font-size: var(--fs-mini); line-height: 16px; }
.today-empty { display: flex; flex-direction: column; gap: 4px; }
.today-empty-title { color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); }
.today-w.is-l .w-foot { gap: 6px; }
.w-link { position: relative; color: var(--text-2); font-weight: var(--fw-medium); text-decoration: none; white-space: nowrap; }
.w-link:hover { color: var(--text-1); }
@media (pointer: coarse) { .w-link::before { content: ""; position: absolute; inset: -14px -8px; } }
@media (max-width: 700px) {
  .today-w .row { font-size: var(--fs-regular); line-height: 20px; }
  .today-w .row > .st, .today-w .row > .row-mark { margin-top: 3px; }
  .today-w .row-why { font-size: var(--fs-small); line-height: var(--lh-small); }
  .today-w.is-l .row { row-gap: 2px; }
  .today-s-title { font-size: var(--fs-small); line-height: var(--lh-small); }
}

/* == 6 tasks + sheet == */
/* Task row parts (§3.4): badge words carry the meaning; the mark only repeats it. */
.task-row .row-meta { min-height: 18px; }
.badge { display: inline-flex; align-items: center; gap: 5px; color: var(--text-2); font-size: var(--fs-mini); line-height: 16px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.badge.is-danger { color: var(--danger); }
.badge.is-warn { color: var(--warn); }
.badge.is-accent { color: var(--accent-text); }
.badge.is-quiet { color: var(--text-3); }
.why-step { color: var(--text-3); font-weight: var(--fw-medium); }
.task-row .row-epic { max-width: 200px; overflow: hidden; text-overflow: ellipsis; }
.row-mark { display: grid; place-items: center; width: 14px; height: 14px; }
/* One-line rows in «Все» and the epic detail: glyph · title · state (truncates first) · date · epic. */
.task-row.is-line { grid-template-columns: 16px minmax(0, max-content) minmax(0, 1fr) auto auto; align-items: center; }
.task-row.is-line > .st { margin-top: 0; }
.row-state { min-width: 0; overflow: hidden; color: var(--text-3); font-size: var(--fs-mini); text-overflow: ellipsis; white-space: nowrap; }
.row-date { display: inline-flex; align-items: center; gap: 5px; color: var(--text-3); font-size: var(--fs-mini); font-variant-numeric: tabular-nums; white-space: nowrap; }
.row-date.is-danger { color: var(--danger); }
.task-row.is-line .row-epic { max-width: 160px; overflow: hidden; color: var(--text-3); font-size: var(--fs-mini); text-overflow: ellipsis; white-space: nowrap; }
.task-row.is-line:has(.st[aria-label="Готово"]) .row-title, .task-row.is-line:has(.st[aria-label="Отменено"]) .row-title { color: var(--text-3); font-weight: var(--fw-regular); }

/* Задачи view (§3.6, §4.3). */
.tasks-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; margin-bottom: 16px; }
.tasks-bar .chips { margin: 0; }
.tasks-seg .seg-count { color: var(--text-3); font-size: var(--fs-micro); line-height: var(--lh-micro); }
.tasks-seg [aria-selected="true"] .seg-count { color: var(--text-2); }
.tasks-note { margin-bottom: 12px; }
.tasks-body { --why-lines: 2; }
.task-group { scroll-margin-top: calc(var(--header-h) + 12px); }
.task-group + .task-group { margin-top: 14px; }
.task-list { margin-top: 2px; }
.tasks-foot { margin-top: 16px; padding: 0 10px; font-size: var(--fs-small); line-height: var(--lh-small); }
.tasks-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 24px 10px; color: var(--text-3); font-size: var(--fs-small); line-height: var(--lh-small); }
.tasks-empty-title { color: var(--text-1); font-size: var(--fs-regular); font-weight: var(--fw-medium); line-height: var(--lh-regular); }
.tasks-empty .button { margin-top: 6px; }
.tasks-down { margin: 8px 0; }
.epics-filter { margin-bottom: 10px; }
.epic-row { grid-template-columns: minmax(0, 1fr) auto 72px 12px; align-items: center; column-gap: 16px; }
.epic-name { display: flex; align-items: center; gap: 8px; min-width: 0; overflow: hidden; color: var(--text-1); font-weight: var(--fw-medium); white-space: nowrap; }
.epic-kind { flex-shrink: 0; padding: 0 6px; border: 1px solid var(--line); border-radius: var(--r-full); color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-regular); line-height: 16px; }
.epic-stats { display: flex; align-items: center; gap: 14px; color: var(--text-2); font-size: var(--fs-mini); font-variant-numeric: tabular-nums; white-space: nowrap; }
.epic-stats .is-danger { display: inline-flex; align-items: center; gap: 5px; color: var(--danger); }
.epic-row .row-date { justify-content: flex-end; }
.epic-row .chev { display: grid; color: var(--text-3); }
.vh-back { gap: 2px; color: var(--text-2); font-size: inherit; }
.vh-back svg { transform: rotate(180deg); }
.tasks-epic-title { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; padding: 0 10px; color: var(--text-1); font-size: var(--fs-regular); font-weight: var(--fw-semibold); line-height: var(--lh-regular); letter-spacing: 0; overflow-wrap: anywhere; }
@media (max-width: 700px) {
  .tasks-body { --why-lines: 3; }
  .tasks-bar { flex-direction: column; align-items: stretch; }
  .tasks-seg { display: flex; }
  .tasks-seg > .segment { flex: 1; }
  .epic-row { grid-template-columns: minmax(0, 1fr) auto 12px; row-gap: 4px; }
  .epic-stats { grid-column: 1 / 2; grid-row: 2; }
  .epic-row .row-date { grid-column: 2; grid-row: 1 / 3; }
  .epic-row .chev { grid-column: 3; grid-row: 1 / 3; }
  .task-row.is-line { min-height: 44px; }
}

/* Task details sheet (§3.7). The frame is WP3's; .is-task lets a long title wrap. */
#sheet.is-task .sheet-title { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; white-space: normal; overflow-wrap: anywhere; }
#sheet.is-task .sheet-head { align-items: flex-start; padding-top: 14px; }
.task-sheet { display: flex; flex-direction: column; gap: 16px; padding-bottom: 8px; color: var(--text-1); }
.ts-top { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--text-3); font-size: var(--fs-mini); line-height: 16px; }
.ts-closed { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line-subtle); border-radius: var(--r-md); background: var(--bg-hover); color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.ts-today { display: flex; align-items: center; gap: 8px; color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); }
.ts-today.is-danger { color: var(--danger); }
.ts-today.is-warn { color: var(--warn); }
.ts-today.is-accent { color: var(--accent-text); }
.ts-label { margin-bottom: 4px; color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-semibold); line-height: 16px; letter-spacing: 0; }
.ts-goal, .ts-step { color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); overflow-wrap: anywhere; }
.ts-goal.is-missing { color: var(--text-3); }
.ts-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 8px 16px; margin: 0; padding-top: 14px; border-top: 1px solid var(--line-subtle); font-size: var(--fs-small); line-height: var(--lh-small); }
.ts-fact { display: contents; }
.ts-fact dt { color: var(--text-3); }
.ts-fact dd { margin: 0; color: var(--text-1); overflow-wrap: anywhere; }
.ts-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; padding-top: 14px; border-top: 1px solid var(--line-subtle); }
.ts-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ts-note { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
@media (max-width: 700px) {
  .ts-chips { gap: 10px 8px; }
  .ts-chips .chip { min-height: 32px; padding: 0 12px; font-size: var(--fs-small); }
  .ts-actions .button { width: 100%; }
}

/* == 7 calendar, health, finance == */
/* View cards (.box): one surface per section with a 13 px h2; views stack them with a 12 px gap. */
.hl, .fin { display: flex; flex-direction: column; gap: 12px; max-width: 920px; }
.box { min-width: 0; padding: 14px 16px; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); }
.box-head { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; min-height: 24px; margin-bottom: 10px; }
.box-head.is-wrap { flex-wrap: wrap; }
.box-head h2 { min-width: 0; color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-semibold); line-height: var(--lh-small); letter-spacing: 0; }
.box-aside { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); white-space: nowrap; }
.box-ctl { display: flex; flex-wrap: wrap; gap: 8px; }
.box-empty { display: flex; align-items: center; gap: 8px; padding: 4px 0; color: var(--text-3); font-size: var(--fs-small); line-height: var(--lh-small); }
.box-foot { margin-top: 6px; padding: 0 10px; font-size: var(--fs-small); line-height: var(--lh-small); }
.box-note { margin-top: 10px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.box > .section-foot { margin-top: 10px; }
.box-toggle { position: relative; display: inline-flex; align-items: center; gap: 8px; min-height: 28px; padding: 0; background: none; color: var(--text-1); font: inherit; text-align: left; }
.box-toggle .group-count { color: var(--text-3); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.box-toggle-word { color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-regular); }
.box-toggle .chev, .cat-rest .chev { display: grid; color: var(--text-3); transition: transform var(--dur-quick); }
.box-toggle[aria-expanded="true"] .chev, .cat-rest[aria-expanded="true"] .chev { transform: rotate(90deg); }
.box.is-collapsed .box-head { margin-bottom: 0; }
.is-flip svg { transform: rotate(180deg); }
.hl .row-list, .fin .row-list { --why-lines: 1; margin: 0 -10px; }

/* Charts (§1.6.14): SVG plot stretched to the box (strokes keep their width), HTML points and labels in percent. */
.chart { position: relative; margin: 0; outline-offset: 4px; }
.ch-plot { position: relative; height: 176px; margin-top: 18px; touch-action: pan-y; cursor: crosshair; }
.ch-svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
.ch-area { position: absolute; top: 0; right: 0; bottom: 0; left: 40px; }
.ch-grid { stroke: var(--line-subtle); stroke-width: 1; }
.ch-target { stroke: var(--line-strong); stroke-width: 1.25; stroke-dasharray: 5 4; }
.ch-line { fill: none; stroke: var(--text-2); stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; }
.ch-hop { fill: none; stroke: var(--text-3); stroke-width: 1.25; stroke-dasharray: 3 3; }
.ch-y { position: absolute; left: 0; transform: translateY(calc(-100% - 2px)); color: var(--text-3); font-size: var(--fs-micro); line-height: var(--lh-micro); white-space: nowrap; pointer-events: none; }
.ch-pt { position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; background: var(--text-2); box-shadow: 0 0 0 2px var(--bg-card); pointer-events: none; }
.ch-pt.is-partial { border: 1.5px solid var(--text-2); background: var(--bg-card); }
.ch-pt.is-active { width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; background: var(--text-1); }
.ch-pt.is-partial.is-active { border-color: var(--text-1); background: var(--bg-card); }
.ch-xaxis { position: relative; height: 16px; margin: 6px 0 0 40px; }
.ch-x { position: absolute; top: 0; transform: translateX(-50%); color: var(--text-3); font-size: var(--fs-micro); line-height: 16px; white-space: nowrap; }
.ch-x.is-last { transform: translateX(calc(-100% + 6px)); }
.ch-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 16px; margin-top: 8px; }
.ch-cap { min-height: 16px; color: var(--text-2); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.ch-legend { display: inline-flex; align-items: center; gap: 6px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); white-space: nowrap; }
.ch-dash { width: 16px; border-top: 1.25px dashed var(--line-strong); }
.tn { font-variant-numeric: tabular-nums lining-nums; }

/* Календарь (§4.4): timeline 1fr + a 280 px sticky rail above 700 px at every width. */
.cal { display: grid; grid-template-columns: minmax(0, 1fr) 280px; align-items: start; gap: 24px; }
.cal-main { min-width: 0; }
.cal-rail { position: sticky; top: calc(var(--header-h) + 16px); display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.cal-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.cal-nav { display: flex; align-items: center; gap: 2px; }
.cal-nav .button[aria-disabled="true"] { color: var(--text-3); }
.cal-date { color: var(--text-1); font-size: var(--fs-regular); font-weight: var(--fw-semibold); line-height: var(--lh-regular); letter-spacing: 0; }
.cal-summary { margin: 6px 0 14px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.cal-main > .state-banner { margin-bottom: 12px; }
.cal-week { display: none; }
.tl { --why-lines: 1; margin: 0; padding: 0; list-style: none; }
.tl-item { display: block; }
.tl-row { display: grid; grid-template-columns: 44px 14px minmax(0, 1fr) auto; align-items: center; column-gap: 10px; width: 100%; min-height: 40px; padding: 6px 8px; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); text-align: left; }
button.tl-row { cursor: pointer; }
button.tl-row:hover { background: var(--bg-hover); }
.tl-row:focus-visible { outline: none; background: var(--bg-selected); box-shadow: inset 0 0 0 1px var(--accent-border); }
.tl-time { color: var(--text-3); font-size: var(--fs-mini); line-height: 18px; }
.tl-mark { display: flex; align-items: center; justify-content: center; height: 18px; }
.tl-bar { display: block; width: 2px; height: 14px; border-radius: 1px; background: var(--line-strong); }
.tl-bar.is-dashed { width: 0; border-left: 2px dashed var(--line-strong); border-radius: 0; background: none; }
.tl-title { min-width: 0; overflow: hidden; font-weight: var(--fw-medium); text-overflow: ellipsis; white-space: nowrap; }
.tl-meta { display: flex; align-items: center; gap: 6px; min-width: 0; max-width: 280px; overflow: hidden; color: var(--text-3); font-size: var(--fs-mini); text-overflow: ellipsis; white-space: nowrap; }
.tl-meta.is-accent { color: var(--accent-text); }
.tl-row .row-why { grid-column: 3 / -1; }
.tl-join { grid-column: 3 / -1; justify-self: start; margin: 6px 0 2px; }
.tl-row.is-past .tl-time, .tl-row.is-past .tl-title, .tl-row.is-done .tl-title { color: var(--text-3); font-weight: var(--fw-regular); }
.tl-row.is-block .tl-title { color: var(--text-2); font-weight: var(--fw-regular); }
.tl-row.is-past.is-task:not(.is-done) .tl-title { color: var(--text-2); }
.tl-now { display: grid; grid-template-columns: 44px minmax(0, 1fr); align-items: center; column-gap: 10px; height: 16px; padding: 0 8px; }
.tl-now-time { color: var(--accent-text); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: 16px; }
.tl-now-line { height: 1px; background: var(--accent); }
.tl-allday { display: flex; flex-direction: column; gap: 4px; margin: 0 0 10px; padding: 0; list-style: none; }
.tl-ad { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; min-height: 32px; padding: 6px 10px; border: 1px solid var(--line-subtle); border-radius: var(--r-sm); background: var(--bg-raised); font-size: var(--fs-small); line-height: var(--lh-small); }
.tl-ad-k, .tl-ad-meta { color: var(--text-3); font-size: var(--fs-mini); white-space: nowrap; }
.tl-ad-title { overflow: hidden; color: var(--text-1); text-overflow: ellipsis; white-space: nowrap; }
.cal-nodata, .cal-empty { display: flex; align-items: center; gap: 8px; padding: 8px; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.cal-empty { color: var(--text-3); }
.cal-box { --why-lines: 1; min-width: 0; padding: 12px; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); }
.cal-box-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.cal-box-h { margin-bottom: 6px; color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-semibold); line-height: var(--lh-small); letter-spacing: 0; }
.cal-box-head .cal-box-h { margin: 0; }
.cal-box-h .group-count { margin-left: 4px; color: var(--text-3); font-weight: var(--fw-medium); }
.cal-box .row-list { margin: 0 -6px; }
.cal-box .row { padding: 6px; }
.cal-mnav { display: flex; gap: 2px; }
.cal-wk, .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-wk span { color: var(--text-3); font-size: var(--fs-micro); line-height: 24px; text-align: center; }
.cal-d, .cal-wd { position: relative; display: grid; place-items: center; height: 32px; padding: 0; border: 0; background: none; color: var(--text-2); font-size: var(--fs-mini); font-variant-numeric: tabular-nums; }
.cal-dn { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; }
:is(.cal-d, .cal-wd):hover .cal-dn { background: var(--bg-hover); color: var(--text-1); }
.cal-d.is-other { color: var(--text-3); }
:is(.cal-d, .cal-wd).is-out .cal-dn { color: var(--text-4); }
:is(.cal-d, .cal-wd)[aria-current="date"] .cal-dn { background: var(--bg-selected); color: var(--text-1); font-weight: var(--fw-semibold); }
:is(.cal-d, .cal-wd)[aria-pressed="true"] .cal-dn { box-shadow: 0 0 0 1.5px var(--accent-border); color: var(--text-1); }
.cal-d:focus-visible, .cal-wd:focus-visible { outline: none; }
:is(.cal-d, .cal-wd):focus-visible .cal-dn { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.cal-dot { position: absolute; bottom: 1px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--text-3); }
.cal-muted { display: flex; align-items: center; gap: 6px; padding: 2px 0; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.cal-tz { padding: 0 4px; }
.cal-next-day + .cal-next-day { margin-top: 8px; }
.cal-next-h { padding: 2px 0; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.cal-next-row { position: relative; display: grid; grid-template-columns: 40px 14px minmax(0, 1fr); align-items: center; column-gap: 8px; width: 100%; min-height: 28px; margin: 0 -6px; padding: 4px 6px; border-radius: var(--r-sm); background: none; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); text-align: left; box-sizing: content-box; }
.cal-next-row:hover { background: var(--bg-hover); }
.cal-next-at { color: var(--text-3); font-size: var(--fs-mini); }
.cal-next-row .tl-bar { justify-self: center; height: 12px; }
.cal-next-row .st { justify-self: center; }
.cal-next-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-sheet { padding-bottom: 8px; }
.cal-sheet .cal-mnav { justify-content: flex-end; margin-bottom: 4px; }
.cal-sheet .cal-d { height: 44px; font-size: var(--fs-small); }
.cal-sheet .cal-dn { width: 36px; height: 36px; }
.cal-sheet .cal-dot { bottom: 2px; }

/* Здоровье (§4.5). */
.hl-attn-list { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.hl-attn { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 36px; padding: 7px 12px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-card); color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.hl-attn > span { flex: 1 1 180px; min-width: 0; }
.hp-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); align-items: start; gap: 16px 32px; }
.hp-label { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.hp-big { color: var(--text-1); font-size: var(--fs-metric); font-weight: var(--fw-medium); line-height: var(--lh-metric); letter-spacing: var(--tr-metric); white-space: nowrap; }
.hp-big.is-dim { color: var(--text-2); }
.hp-big .unit, .fh-value .unit { font-size: var(--fs-small); font-weight: var(--fw-regular); letter-spacing: 0; }
.hp-sub { margin: 2px 0 8px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.hp-macros { display: flex; flex-direction: column; gap: 10px; padding-top: 2px; }
.hp-macro { display: grid; grid-template-columns: auto minmax(0, 1fr); row-gap: 5px; column-gap: 12px; }
.hp-mk { color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.hp-mv { color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); text-align: right; }
.hp-macro .progress-track { grid-column: 1 / -1; }
.hp-goal { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-subtle); color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.trend-line { color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); }
.meal-list, .sup-list, .cat-list, .cat-sub, .acc-list { margin: 0; padding: 0; list-style: none; }
.meal-row { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: baseline; column-gap: 10px; min-height: 40px; padding: 6px 0; border-top: 1px solid var(--line-subtle); font-size: var(--fs-small); line-height: var(--lh-small); }
.meal-row:first-child { border-top: 0; }
.mr-time { color: var(--text-3); font-size: var(--fs-mini); }
.mr-title { min-width: 0; overflow: hidden; color: var(--text-1); text-overflow: ellipsis; white-space: nowrap; }
.mr-kcal { color: var(--text-1); white-space: nowrap; }
.mr-macro { grid-column: 2 / -1; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.meal-row.is-total .mr-title, .meal-row.is-total .mr-kcal { font-weight: var(--fw-semibold); }
.sup-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--line-subtle); }
.sup-row:first-child { border-top: 0; }
.sup-row.is-warning { justify-content: flex-start; align-items: center; gap: 8px; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.sup-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sup-name { color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); overflow-wrap: anywhere; }
.sup-meta, .sup-note { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.sup-days { display: flex; flex-shrink: 0; flex-direction: column; align-items: flex-end; text-align: right; }
.sup-n { display: inline-flex; align-items: center; gap: 6px; color: var(--text-1); font-size: 15px; font-weight: var(--fw-medium); line-height: 20px; white-space: nowrap; }
.sup-days.is-warn .sup-n { color: var(--warn); }
.sup-days.is-unknown { flex-direction: row; align-items: center; gap: 6px; }
.sup-days.is-unknown .sup-n { color: var(--text-3); font-size: var(--fs-small); font-weight: var(--fw-regular); }
.sup-until { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); white-space: nowrap; }

/* Финансы (§4.6). */
.fin-bar { display: flex; justify-content: flex-start; }
.fin-src { margin-left: 4px; }
.fh-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px 28px; }
.fh-block { min-width: 0; }
.fh-label { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.fh-value { margin-top: 2px; color: var(--text-1); font-size: var(--fs-metric); font-weight: var(--fw-medium); line-height: var(--lh-metric); letter-spacing: var(--tr-metric); white-space: nowrap; }
.fh-value.is-dim { color: var(--text-2); }
.fh-ge { color: var(--text-2); }
.fh-sub { display: flex; align-items: center; gap: 6px; margin-top: 4px; color: var(--text-2); font-size: var(--fs-mini); line-height: var(--lh-mini); overflow-wrap: anywhere; }
.fh-sub.is-warn { color: var(--text-1); }
.fh-sub.is-list { display: block; }
.nw { white-space: nowrap; }
.fh-note { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-subtle); color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.fin-down { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.fin-down-text { flex: 1 1 240px; min-width: 0; }
.fm-line { margin-bottom: 8px; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.cat-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(80px, 160px) minmax(0, max-content); align-items: center; column-gap: 16px; min-height: 36px; padding: 6px 0; border-top: 1px solid var(--line-subtle); font-size: var(--fs-small); line-height: var(--lh-small); }
.cat-list > li:first-child { border-top: 0; }
.cat-name { min-width: 0; overflow: hidden; color: var(--text-1); text-overflow: ellipsis; white-space: nowrap; }
.cat-amt { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 0 8px; color: var(--text-1); text-align: right; white-space: nowrap; }
.cat-amt .unit { color: var(--text-3); }
.cat-over { display: inline-flex; align-items: center; gap: 5px; color: var(--warn); font-size: var(--fs-mini); }
.cat-rest-item { border-top: 1px solid var(--line-subtle); }
.cat-rest { display: grid; grid-template-columns: minmax(0, 1fr) auto 12px; align-items: center; gap: 12px; width: 100%; min-height: 36px; padding: 6px 0; background: none; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); text-align: left; }
.cat-rest .cat-name { color: var(--text-2); }
.cat-row.is-plain { grid-template-columns: minmax(0, 1fr) auto; padding-left: 12px; }
.plan-row .row-meta .num { color: var(--text-1); }
.acc-group + .acc-group { margin-top: 12px; }
.acc-gh { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0 6px; border-bottom: 1px solid var(--line-subtle); color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-semibold); line-height: var(--lh-mini); }
.acc-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name amt" "meta amt"; column-gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--line-subtle); }
.acc-row:last-child { border-bottom: 0; }
.acc-name { grid-area: name; overflow: hidden; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); text-overflow: ellipsis; white-space: nowrap; }
.acc-meta { grid-area: meta; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.acc-amt { grid-area: amt; display: inline-flex; align-items: center; align-self: center; gap: 6px; color: var(--text-1); font-size: var(--fs-small); text-align: right; white-space: nowrap; }

@media (pointer: coarse) {
  .cal-next-row { min-height: 36px; }
  .box-toggle::before { content: ""; position: absolute; inset: -8px -4px; }
}
@media (max-width: 700px) {
  .box { padding: 14px; }
  .box-head h2, .cal-box-h { font-size: var(--fs-regular); line-height: var(--lh-regular); }
  .hl .row-list, .fin .row-list { margin: 0 -8px; }
  .ch-plot { height: 148px; }
  .cal { display: block; }
  .cal-rail { position: static; margin-top: 20px; }
  .cal-month-box { display: none; }
  .cal-head { gap: 4px 8px; }
  .cal-week { display: block; margin: 8px 0 12px; }
  .cal-week-head { display: flex; align-items: center; justify-content: space-between; }
  .cal-month-btn { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; padding: 0 4px; background: none; color: var(--text-1); font-size: var(--fs-regular); font-weight: var(--fw-semibold); }
  .cal-month-btn svg { color: var(--text-3); }
  .cal-week-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
  .cal-wd { height: 56px; grid-template-rows: 14px 32px; align-content: center; gap: 2px; font-size: var(--fs-regular); }
  .cal-wd-name { color: var(--text-3); font-size: var(--fs-micro); line-height: 14px; }
  .cal-wd .cal-dn { width: 32px; height: 32px; }
  .cal-wd .cal-dot { bottom: 0; }
  .cal-summary { margin-bottom: 0; }
  .tl-row { min-height: 44px; padding: 8px 4px; font-size: var(--fs-regular); line-height: 20px; }
  .tl-time, .tl-mark { height: 20px; line-height: 20px; }
  .tl-meta { max-width: 130px; font-size: var(--fs-small); }
  .tl-meta.is-wide { grid-column: 3 / -1; max-width: none; margin-top: 1px; }
  .tl-now { padding: 0 4px; }
  .tl-ad { font-size: var(--fs-regular); line-height: 20px; }
  .cal-next-row { font-size: var(--fs-regular); line-height: 20px; }
  .hp-grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .meal-row, .sup-name, .acc-name, .cat-row, .cat-rest, .fm-line, .hl-attn, .fin-down, .trend-line { font-size: var(--fs-regular); line-height: 20px; }
  .mr-macro, .sup-meta, .sup-note, .acc-meta, .sup-until { font-size: var(--fs-small); line-height: var(--lh-small); }
  .cat-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; }
  .cat-bar { grid-column: 1 / -1; grid-row: 2; }
  .cat-row.is-over .cat-name { grid-column: 1 / -1; }
  .cat-row.is-over .cat-amt { grid-column: 1 / -1; grid-row: 3; justify-content: flex-start; }
  .fh-grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .box-toggle { min-height: 44px; }
  .box.is-collapsed { padding-top: 6px; padding-bottom: 6px; }
}

/* == 8 hsk, alfred, settings, mail, lock == */
/* Shared: a 13 px section h2, quiet notes, the one-surface box, groups and confirm sheets. */
.wp8-h2 { color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-semibold); line-height: var(--lh-small); letter-spacing: 0; }
.wp8-note { margin-top: 12px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.wp8-group + .wp8-group { margin-top: 12px; }
.wp8-group > .row-list { padding-top: 2px; }
.group-head.is-static { cursor: default; }
.group-head > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wp8-group .group-head .chev { display: grid; }
.row > .row-mark { display: grid; place-items: center; width: 16px; height: 16px; color: var(--text-3); }
.row > .row-mark svg { width: 14px; height: 14px; }
.wp8-confirm p { color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); overflow-wrap: anywhere; }
.wp8-confirm-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.button.danger.is-filled { border-color: var(--danger-line); background: var(--danger-soft); color: var(--danger); }
.button.danger.is-filled:hover { background: var(--danger-soft); border-color: var(--danger); }

/* HSK (§4.7): stat strip, primary action, one column of groups, a 68ch lesson with exercises. */
.hsk-top, .hsk-list, .hsk-block, .lesson, .settings, .mail { max-width: 720px; }
.hsk-top { display: flex; flex-direction: column; gap: 14px; margin-bottom: 20px; }
.hsk-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); }
.hsk-stat { min-width: 0; padding: 12px 16px; }
.hsk-stat + .hsk-stat { border-left: 1px solid var(--line-subtle); }
.hsk-stat dt { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.hsk-stat dd { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; margin: 4px 0 0; color: var(--text-1); font-size: var(--fs-title); font-weight: var(--fw-medium); line-height: var(--lh-title); white-space: normal; }
.hsk-stat dd.is-dim { color: var(--text-2); }
.hsk-stat-sub { color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-regular); line-height: var(--lh-mini); }
.hsk-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.hsk-top > .section-foot { margin-top: -4px; }
.hsk-list { margin-bottom: 24px; }
.hsk-row .row-title { font-size: var(--fs-small); }
.hsk-due { display: inline-flex; align-items: center; gap: 6px; }
.hsk-due.is-danger { color: var(--danger); }
.hsk-more { margin: 6px 10px 2px; font-size: var(--fs-small); }
.hsk-block { margin-top: 8px; padding: 14px 16px; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); }
.view > .wp8-note { max-width: 720px; }

.lesson-back { gap: 4px; font-size: var(--fs-small); }
.lesson-back svg { width: 14px; height: 14px; }
.lesson { --measure: 68ch; }
.lesson-head { margin-bottom: 16px; }
.lesson-kicker { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.lesson-title { margin-top: 4px; color: var(--text-1); font-size: var(--fs-title); font-weight: var(--fw-semibold); line-height: var(--lh-title); letter-spacing: var(--tr-title); }
.lesson-content { max-width: var(--measure); color: var(--text-1); font-size: var(--fs-regular); line-height: 1.7; white-space: pre-line; overflow-wrap: anywhere; }
.lesson-examples { display: flex; flex-direction: column; gap: 8px; max-width: var(--measure); margin: 20px 0 0; padding: 0; list-style: none; }
.lesson-examples li { padding: 10px 14px; border-left: 2px solid var(--line-strong); }
.ex-zh { color: var(--text-1); font-size: var(--fs-title); line-height: 1.6; }
.ex-py, .ex-ru { margin-top: 2px; color: var(--text-3); font-size: var(--fs-small); line-height: var(--lh-small); }
.lesson-practice { max-width: var(--measure); margin-top: 28px; }
.lesson-practice-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-bottom: 4px; }
.exercise { padding: 20px 0; border-top: 1px solid var(--line-subtle); }
.ex-eyebrow { color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); }
.passage { margin: 10px 0 0; padding: 10px 14px; border-left: 2px solid var(--line-strong); color: var(--text-1); font-size: var(--fs-large); line-height: 1.8; white-space: pre-line; overflow-wrap: anywhere; }
.ex-prompt { margin-top: 10px; color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); overflow-wrap: anywhere; }
.ex-hint { margin-top: 6px; color: var(--text-3); font-size: var(--fs-small); line-height: var(--lh-small); }
.ex-options { display: grid; gap: 6px; margin-top: 12px; }
.ex-option { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-card); color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); text-align: left; }
.ex-option:hover:not(:disabled) { border-color: var(--line-strong); background: var(--bg-hover); }
.ex-option:disabled { opacity: 1; cursor: default; }
.ex-letter { display: grid; place-items: center; flex-shrink: 0; width: 22px; height: 22px; border: 1px solid var(--line); border-radius: var(--r-sm); color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-medium); }
.ex-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.ex-option.is-selected { border-color: var(--accent); background: var(--bg-selected); }
.ex-option.is-selected .ex-letter { border-color: var(--accent); color: var(--accent-text); }
.ex-option.is-right { border-color: var(--line-strong); background: var(--bg-selected); }
.ex-option.is-wrong { border-color: var(--danger-line); border-style: dashed; background: transparent; }
.ex-tag { flex-shrink: 0; color: var(--text-2); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); white-space: nowrap; }
.ex-tag.is-wrong { color: var(--danger); }
.ex-answer-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 52px; margin-top: 12px; padding: 6px; border: 1px dashed var(--line-strong); border-radius: var(--r-md); }
.ex-placeholder { padding: 0 6px; color: var(--text-3); font-size: var(--fs-small); }
.ex-pool { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.word-token { min-height: 36px; padding: 4px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-raised); color: var(--text-1); font-size: var(--fs-large); line-height: 26px; }
.word-token:hover:not(:disabled) { border-color: var(--line-strong); }
.word-token:disabled { opacity: .35; cursor: default; }
.word-token.is-chosen { border-color: var(--line-strong); background: var(--bg-selected); }
.word-token.is-chosen:disabled { opacity: 1; }
.ex-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.ex-result, .ex-reveal { margin-top: 12px; padding: 10px 14px; border-left: 2px solid var(--line-strong); color: var(--text-2); font-size: var(--fs-small); line-height: 1.6; outline-offset: 2px; }
.ex-result > p + p, .ex-reveal > p + p { margin-top: 4px; }
.ex-result.is-wrong { border-left-color: var(--danger); }
.ex-verdict { display: flex; align-items: center; gap: 6px; color: var(--text-1); font-weight: var(--fw-semibold); }
.ex-result.is-wrong .ex-verdict { color: var(--danger); }
.ex-glyph { font-size: var(--fs-regular); line-height: 1; }
.ex-why { color: var(--text-3); }
.lesson-foot { max-width: var(--measure); margin-top: 8px; padding-top: 16px; border-top: 1px solid var(--line-subtle); }
.lesson-score { color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.lesson-score:empty { display: none; }
.lesson-foot-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
@media (pointer: coarse) {
  .word-token { min-height: 44px; }
  .ex-option { min-height: 48px; }
}

/* Альфред (§4.8): a full-height pane — no hero, no card, a 720 px reading column, a hairline above the composer. */
#view:has(> .chat-pane) { display: flex; flex-direction: column; max-width: none; height: calc(100dvh - 2 * var(--panel-inset) - 2px - var(--header-h)); padding-top: 0; padding-bottom: 0; }
#view:has(> .chat-pane) > .state-banner { width: 100%; max-width: 720px; margin: 12px auto 0; }
.chat-pane { position: relative; display: flex; flex: 1; flex-direction: column; min-height: 0; margin: 0 calc(-1 * var(--content-pad)); }
.chat-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 var(--content-pad); scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
.chat-col { width: 100%; max-width: 720px; margin: 0 auto; }
.chat-thread { display: flex; flex-direction: column; padding: 16px 0 20px; }
.chat-dock { flex-shrink: 0; padding: 10px var(--content-pad) 12px; border-top: 1px solid var(--line); background: var(--bg-app); }
.chat-dock .state-banner { margin-bottom: 8px; }
.chat-pill { display: inline-flex; align-items: center; gap: 6px; color: var(--text-2); font-size: var(--fs-mini); line-height: var(--lh-mini); white-space: nowrap; }
.chat-pill .num, .chat-pill [data-elapsed] { font-variant-numeric: tabular-nums; }
.chat-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-3); }
.chat-chips { display: flex; gap: 6px; margin-bottom: 8px; overflow-x: auto; scrollbar-width: none; }
.chat-chips::-webkit-scrollbar { display: none; }
.chat-chips .chip { flex-shrink: 0; }
.chat-form { display: flex; align-items: flex-end; gap: 8px; padding: 6px 6px 6px 12px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--bg-raised); }
.chat-form:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.chat-input { flex: 1; min-width: 0; min-height: 28px; max-height: 45vh; padding: 4px 0; border: 0; background: transparent; color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); resize: none; overflow-y: hidden; }
.chat-input:focus, .chat-input:focus-visible { outline: none; }
.chat-input::placeholder { color: var(--text-4); }
.chat-send { flex-shrink: 0; width: 32px; min-height: 32px; height: 32px; padding: 0; }
.chat-send svg { width: 16px; height: 16px; }
.chat-send.is-busy:disabled { color: var(--text-3); }
.chat-hint { min-height: 16px; margin-top: 6px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.chat-hint:empty { display: none; }
.chat-hint.is-busy { color: var(--text-2); }
.chat-dock { position: relative; }
.chat-jump { position: absolute; z-index: 1; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%); background: var(--bg-elevated); box-shadow: var(--shadow-medium); }
.chat-day { display: flex; align-items: center; gap: 12px; margin: 16px 0 8px; color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); }
.chat-day::before, .chat-day::after { content: ""; flex: 1; height: 1px; background: var(--line-subtle); }
.msg { margin-top: 14px; }
.msg.is-grouped { margin-top: 4px; }
.msg.is-user { display: flex; flex-direction: column; align-items: flex-end; margin-left: 15%; }
.msg-bubble { max-width: 100%; padding: 8px 12px; border-radius: var(--r-md); background: var(--bg-hover); color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); white-space: pre-wrap; overflow-wrap: anywhere; }
.msg.is-failed .msg-bubble { box-shadow: inset 0 0 0 1px var(--warn-line); }
.msg-task { margin-left: 8px; vertical-align: 1px; white-space: nowrap; }
.msg-meta { margin-top: 4px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.msg-fail { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px 6px; margin-top: 6px; color: var(--text-2); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.msg-label { margin-bottom: 4px; color: var(--text-3); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); }
.msg-run { display: flex; align-items: center; gap: 8px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.msg-run [data-elapsed] { font-variant-numeric: tabular-nums; }
.msg-run-note { margin-top: 4px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.msg-error { display: flex; align-items: baseline; gap: 8px; padding: 8px 12px; border: 1px solid var(--warn-line); border-radius: var(--r-md); color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); overflow-wrap: anywhere; }
.msg-error > .sig-warn { position: relative; top: 1px; }
.msg-actions { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.chat-notice, .chat-state { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 12px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.chat-state.is-error { padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-card); color: var(--text-1); }
.chat-empty { margin: auto 0; padding: 48px 0 24px; text-align: center; }
.chat-empty h2 { color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); letter-spacing: 0; }
.chat-empty p { max-width: 420px; margin: 6px auto 0; color: var(--text-3); font-size: var(--fs-small); line-height: var(--lh-small); }
.chat-skel { display: flex; flex-direction: column; gap: 6px; margin-top: 18px; }
.chat-skel .skeleton { height: 12px; width: 72%; }
.chat-skel .skeleton + .skeleton { width: 46%; }
.chat-skel.is-user { align-items: flex-end; }
.chat-skel.is-user .skeleton { width: 38%; height: 32px; }
.chat-skel.is-user .skeleton + .skeleton { display: none; }
/* Alfred's Markdown (public/markdown.js): 15 px reading text, h3/h4 at 14 px weight 600, scrolling tables. */
.md { color: var(--text-1); font-size: var(--fs-regular); line-height: var(--lh-regular); overflow-wrap: anywhere; }
.md > * + * { margin-top: 8px; }
.md :is(h3, h4) { margin-top: 14px; color: var(--text-1); font-size: 14px; font-weight: var(--fw-semibold); line-height: 20px; letter-spacing: 0; }
.md :is(ul, ol) { margin-bottom: 0; padding-left: 22px; }
.md li + li { margin-top: 2px; }
.md blockquote { margin: 8px 0 0; padding: 2px 0 2px 12px; border-left: 2px solid var(--line-strong); color: var(--text-2); }
.md code { padding: 1px 4px; border-radius: var(--r-xs); background: var(--bg-hover); font-family: var(--font-mono); font-size: .88em; }
.md pre { margin: 8px 0 0; padding: 10px 12px; overflow-x: auto; border: 1px solid var(--line-subtle); border-radius: var(--r-md); background: var(--bg-card); font-size: var(--fs-small); line-height: var(--lh-small); white-space: pre; }
.md pre code { padding: 0; background: none; font-size: inherit; }
.md a { color: var(--accent-text); text-decoration: underline; text-decoration-color: var(--accent-border); text-underline-offset: 2px; }
.md hr { height: 1px; margin: 12px 0; border: 0; background: var(--line-subtle); }
.md .table-scroll { margin-top: 8px; border: 1px solid var(--line-subtle); border-radius: var(--r-md); }
.md table { font-size: var(--fs-small); line-height: var(--lh-small); }
.md :is(th, td) { padding: 6px 10px; border-bottom: 1px solid var(--line-subtle); text-align: left; vertical-align: top; }
.md th { color: var(--text-2); font-weight: var(--fw-semibold); white-space: nowrap; }
.md tr:last-child td { border-bottom: 0; }
/* A reply that arrived while away: an accent dot on Альфред until #alfred is opened. */
.nav-item.has-unseen::after, .tab.has-unseen::after { content: ""; position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.nav-item.has-unseen::after { right: 8px; top: 50%; margin-top: -3px; }
.tab.has-unseen::after { top: 8px; left: calc(50% + 8px); }

/* Настройки (§4.9): one 720 px column of boxes with h2 headings. */
.settings { display: flex; flex-direction: column; gap: 12px; }
.set-section { padding: 14px 16px; border: 1px solid var(--line-subtle); border-radius: var(--r-lg); background: var(--bg-card); box-shadow: var(--card-shadow); }
.set-section > .wp8-h2 { margin-bottom: 10px; }
.set-summary { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.set-list { --why-lines: 2; margin: 0 -10px; }
.src-row .row-meta .chev { display: grid; }
.src-ok { display: grid; color: var(--text-3); }
.src-row.is-error .row-why { color: var(--text-2); }
.src-row.is-info { cursor: default; }
.dev-row .row-mark { color: var(--text-2); }
.dev-row.is-idle .row-title { color: var(--text-3); font-weight: var(--fw-regular); }
.set-state { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding: 6px 0; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.set-foot { display: flex; align-items: baseline; gap: 8px; margin-top: 10px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.set-foot.is-warn { color: var(--text-2); }
.set-foot > .sig-warn { position: relative; top: 1px; }
.set-revoke { margin: 10px 0 0 -10px; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; padding: 10px 0; border-top: 1px solid var(--line-subtle); }
.set-section > .wp8-h2 + .set-row { border-top: 0; padding-top: 0; }
.set-text { min-width: 0; }
.set-text h3 { color: var(--text-1); font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-small); }
.set-text p { margin-top: 2px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.set-text .set-warn { margin-top: 6px; }
.set-control { flex-shrink: 0; }
.set-warn { display: flex; align-items: baseline; gap: 8px; color: var(--text-2); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.set-warn > .sig-warn { position: relative; top: 1px; }
.set-line { margin-top: 4px; color: var(--text-1); font-size: var(--fs-small); line-height: var(--lh-small); }
.set-line.is-quiet { margin-top: 8px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.set-line + .set-warn { margin-top: 4px; }
.set-section .set-row:has(+ .set-line), .set-line + .set-row { border-top: 0; }
/* «Добавить устройство»: the whole 24-character code on one line at 390 px. */
.pair { padding: 4px 0 8px; }
.pair-label { color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.pair-code { margin-top: 6px; color: var(--text-1); font-family: var(--font-mono); font-size: min(22px, 5vw); font-weight: var(--fw-medium); line-height: 1.4; letter-spacing: 0; white-space: nowrap; user-select: all; }
.pair-code.is-expired { color: var(--text-3); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.pair-timer { display: flex; align-items: center; gap: 6px; margin-top: 6px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.pair-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.pair-hint { margin-top: 12px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }

/* Почта (§4.10): hero, «Требует действия» rows (next action first), «К сведению» collapsed, mailboxes. */
.mail { display: flex; flex-direction: column; gap: 16px; }
.mail-hero { display: flex; flex-direction: column; gap: 2px; }
.mail-when { display: none; margin-bottom: 6px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.mail-count { color: var(--text-1); font-size: var(--fs-metric); font-weight: var(--fw-medium); line-height: var(--lh-metric); letter-spacing: var(--tr-metric); }
.mail-count.is-dim { color: var(--text-2); }
.mail-count-label { color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.mail-problems { display: flex; align-items: center; gap: 8px; margin-top: 4px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.mail-hero > .section-foot { margin-top: 4px; }
.mail .wp8-group + .wp8-group { margin-top: 0; }
.mail .row-list { --why-lines: 2; }
.mail-act .row-title { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
.mail-act .row-mark { color: var(--text-2); }
.mail-act .row-meta, .mail-info .row-meta { max-width: min(220px, 34vw); min-width: 0; }
.mail-sender { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.mail-info .row-title { font-weight: var(--fw-regular); }
.mail-box { min-height: 36px; }
.mail-box .row-meta { color: var(--text-2); font-size: var(--fs-small); }
.mail-box.is-problem .row-why { color: var(--text-2); }
.mail-zero { padding: 6px 10px 0 36px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }

/* Вход (§4.11): no card; a centred 320 px column about 30% from the top. */
.lock { min-height: 100vh; min-height: 100dvh; padding: max(16px, env(safe-area-inset-top)) 16px 24px; background: var(--bg-app); }
.lock-col { display: flex; flex-direction: column; align-items: stretch; width: 100%; max-width: 320px; margin: 0 auto; padding-top: max(48px, calc(30vh - 120px)); }
.lock-col > .logo-mark { margin-bottom: 20px; }
.lock-title { color: var(--text-1); font-size: var(--fs-title); font-weight: var(--fw-semibold); line-height: var(--lh-title); letter-spacing: var(--tr-title); }
.lock-help { margin-top: 6px; color: var(--text-2); font-size: var(--fs-small); line-height: var(--lh-small); }
.lock-form { display: flex; flex-direction: column; margin-top: 24px; }
.lock-label { margin-bottom: 6px; color: var(--text-2); font-size: var(--fs-mini); font-weight: var(--fw-medium); line-height: var(--lh-mini); }
.lock-input { width: 100%; height: 44px; padding: 0 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-raised); color: var(--text-1); font-family: var(--font-mono); font-size: 16px; font-variant-numeric: tabular-nums; letter-spacing: 0; text-align: center; }
.lock-input::placeholder { color: var(--text-4); }
.lock-input:focus, .lock-input:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.lock-input.is-invalid { border-color: var(--danger); }
.lock-input.is-invalid:focus { box-shadow: 0 0 0 3px var(--danger-soft); }
.lock-submit { width: 100%; min-height: 40px; margin-top: 10px; }
.lock-error { display: flex; align-items: flex-start; gap: 6px; min-height: 40px; margin-top: 10px; color: var(--danger); font-size: var(--fs-small); line-height: var(--lh-small); }
.lock-error svg { margin-top: 2px; }

@media (max-width: 700px) {
  .hsk-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hsk-stat { padding: 10px 12px; }
  .hsk-stat dd { font-size: var(--fs-large); line-height: var(--lh-large); }
  .hsk-row .row-title { font-size: var(--fs-regular); }
  .lesson-title { font-size: var(--fs-large); line-height: var(--lh-large); }
  .ex-zh { font-size: var(--fs-large); }
  #view:has(> .chat-pane) { height: auto; padding-bottom: 0; }
  .chat-pane { flex: none; height: calc(100dvh - var(--header-h) - var(--tabbar-h) - var(--tabbar-bottom) - 20px); }
  .chat-dock { padding: 8px var(--content-pad); }
  .msg.is-user { margin-left: 10%; }
  html.chat-focused .shell:has(#chat-pane) .tabbar { display: none; }
  .set-row { flex-wrap: wrap; }
  .set-control { width: 100%; }
  .set-control .segmented { display: flex; width: 100%; }
  .set-control .segmented > button { flex: 1; }
  .set-revoke { margin-left: 0; }
  .mail-when { display: block; }
  .lock-col { padding-top: max(24px, calc(22vh - 80px)); }
}
@media (pointer: coarse) {
  .chat-send { width: 40px; height: 40px; min-height: 40px; }
  .chat-input { font-size: 16px; }   /* <16 px makes iOS zoom on focus */
  .chat-form { padding-left: 14px; }
  .set-control .segmented > button { height: 32px; }
}

/* == 9 glass == */
/* Linear × Apple glass. The app floats on an aurora canvas: soft colour fields
   that the frosted surfaces blur. Surfaces are translucent with a lit top edge
   (inset highlight) and a deep soft shadow; content inside keeps v2 tokens.
   prefers-reduced-transparency swaps every glass token for a solid surface. */
html:has(> body > #app > .shell), body:has(> #app > .shell), body { background: var(--canvas); }
.shell { position: relative; isolation: isolate; }
.shell::before { content: ""; position: fixed; inset: -10vmax; z-index: -1; pointer-events: none;
  background:
    radial-gradient(40vmax 32vmax at 12% 8%, var(--aurora-1), transparent 70%),
    radial-gradient(36vmax 30vmax at 92% 18%, var(--aurora-3), transparent 70%),
    radial-gradient(34vmax 26vmax at 46% 52%, var(--aurora-1), transparent 72%),
    radial-gradient(44vmax 34vmax at 60% 105%, var(--aurora-2), transparent 70%); }

/* Frame: the sidebar is a glass column, the content panel disappears so widgets float. */
.sidebar { margin: var(--panel-inset); height: calc(100dvh - 2 * var(--panel-inset)); border: 1px solid var(--glass-line); border-radius: var(--r-glass); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--glass-shadow); top: var(--panel-inset); }
.panel { border: 0; background: transparent; }
.view-header { margin: 0 0 4px; border: 1px solid var(--glass-line); border-radius: var(--r-glass); background: var(--glass-solid); -webkit-backdrop-filter: var(--glass-blur-strong); backdrop-filter: var(--glass-blur-strong); box-shadow: var(--glass-shadow); top: var(--panel-inset); }
.view-header h1 { font-family: var(--font-display); font-size: 17px; letter-spacing: -0.015em; }
.nav-item { min-height: 32px; border-radius: 10px; transition: background var(--dur-fade) var(--ease-out), color var(--dur-fade) var(--ease-out); }
.nav-item[aria-current="page"] { background: var(--glass-strong); box-shadow: inset 0 0 0 1px var(--glass-line), 0 1px 0 0 var(--glass-edge) inset; }
.nav-item[aria-current="page"] svg { color: var(--accent-text); }
.brand { font-family: var(--font-display); letter-spacing: -0.01em; }

/* Widgets: frosted cards with an iOS corner and a lit top edge. */
.w { border: 1px solid var(--glass-line); border-radius: var(--r-glass); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--glass-shadow); transition: transform var(--dur-regular) var(--ease-out), box-shadow var(--dur-regular) var(--ease-out), background var(--dur-regular) var(--ease-out); }
.w::before { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; background: linear-gradient(180deg, var(--glass-edge), transparent 34%); opacity: .14; }
a.w:hover, button.w:hover, .w:has(> a:only-child):hover { background: var(--glass-strong); box-shadow: var(--glass-shadow-lift); transform: translateY(-1px); }
.w-slot { border-radius: var(--r-glass); }
.w-head, .w-label, .w-head :is(h2, h3) { font-weight: var(--fw-medium); letter-spacing: -0.003em; }
.w-metric { font-family: var(--font-display); font-weight: var(--fw-semibold); letter-spacing: -0.032em; }
.w-metric small, .w-metric .unit { font-family: var(--font-sans); font-weight: var(--fw-medium); letter-spacing: 0; }
.w-foot { color: var(--text-3); }

/* Rows inside glass: soft rounded hover like Linear lists. */
.row { border-radius: var(--r-glass-sm); transition: background var(--dur-fade) var(--ease-out); }
.row:hover { background: var(--glass-strong); }
.today-w .w-head { padding-bottom: 2px; }

/* Signals glow like status lights. */
.sig-danger { box-shadow: var(--danger-glow); }
.sig-now { box-shadow: var(--accent-glow); }
.progress-track { height: 5px; background: var(--glass-strong); box-shadow: inset 0 0 0 1px var(--glass-line); }
.progress-track span { background: var(--accent-grad); box-shadow: var(--accent-glow); }

/* Controls: glass pills and buttons. */
.chip { border-color: var(--glass-line); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
.chip.is-danger { background: var(--danger-soft); border-color: var(--danger-line); }
.chip.is-warn { background: var(--warn-soft); border-color: var(--warn-line); }
.attention { gap: 6px; }
.attention .chip { min-height: 28px; padding: 0 12px; }
.button { border-radius: 10px; border-color: var(--glass-line); background-color: var(--glass); }
.button.primary { background: var(--accent-grad); box-shadow: var(--accent-glow); }
.icon-button { border-radius: 10px; }
.segmented { border-color: var(--glass-line); border-radius: 10px; background: var(--glass); }
.segmented > [aria-pressed="true"], .segmented > [aria-selected="true"], .segmented > [aria-current="page"] { border-radius: 8px; background: var(--glass-strong); box-shadow: 0 1px 0 0 var(--glass-edge) inset, 0 1px 3px var(--scrim); }

/* Overlays: sheets and toast are the strongest glass. */
dialog.sheet { background: var(--glass-solid); -webkit-backdrop-filter: var(--glass-blur-strong); backdrop-filter: var(--glass-blur-strong); box-shadow: var(--glass-shadow-lift); }
dialog.sheet.is-side { margin: var(--panel-inset); height: calc(100dvh - 2 * var(--panel-inset)); border: 1px solid var(--glass-line); border-radius: var(--r-glass); }
dialog.sheet.is-bottom { border-radius: 28px 28px 0 0; border-color: var(--glass-line); }
#toast { border-color: var(--glass-line); border-radius: 14px; background: var(--glass-solid); -webkit-backdrop-filter: var(--glass-blur-strong); backdrop-filter: var(--glass-blur-strong); box-shadow: var(--glass-shadow-lift); }

/* Editing: widgets lift like iOS jiggle mode. */
.board.is-editing .w-slot-body > * { border-style: solid; border-color: var(--glass-edge); }
.w-slot.is-lifted .w-slot-body > * { box-shadow: var(--glass-shadow-lift); background: var(--glass-strong); }

@media (max-width: 700px) {
  .view-header { margin: 0; border-width: 0 0 1px; border-radius: 0; }
  .tabbar, .edit-toolbar { border-color: var(--glass-line); background: var(--glass-solid); -webkit-backdrop-filter: var(--glass-blur-strong); backdrop-filter: var(--glass-blur-strong); box-shadow: var(--glass-shadow-lift); }
  .tab[aria-current="page"] { background: var(--glass-strong); color: var(--accent-text); box-shadow: 0 1px 0 0 var(--glass-edge) inset; }
}
@media (prefers-reduced-motion: reduce) {
  .w, .row, .nav-item { transition: none; }
  a.w:hover, button.w:hover { transform: none; }
}

/* Follow-ups after owner feedback (2026-10-07): epic accordion, supply reminders. */
.epics-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.epics-top .chips { margin: 0; }
.epic-acc { border-radius: var(--r-glass-sm); }
.epic-acc.is-open { background: var(--glass); box-shadow: inset 0 0 0 1px var(--glass-line); }
.epic-acc + .epic-acc { margin-top: 2px; }
.epic-row { text-align: left; }
.epic-row .chev svg { transition: transform var(--dur-regular) var(--ease-out); }
.epic-row[aria-expanded="true"] .chev svg { transform: rotate(90deg); }
.epic-body { padding: 0 6px 10px 18px; }
.w-line.is-warn { color: var(--warn); }
.sup-remind { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); text-align: left; }
.sup-remind svg { width: 12px; height: 12px; flex-shrink: 0; }
.sup-remind.is-set { padding: 0; border: 0; background: none; cursor: pointer; }
.sup-remind.is-set:hover { color: var(--text-1); }
.sup-remind.is-missing { color: var(--warn); flex-wrap: wrap; }
.sup-remind .link-button { margin-left: 2px; }
@media (prefers-reduced-motion: reduce) { .epic-row .chev svg { transition: none; } }

/* Mobile pass (2026-10-07): sticky header flush to the top, roomier phone widgets. */
.view-header { top: 0; }
.lbl-short { display: none; }
@media (max-width: 700px) {
  /* The header covers the status-bar area itself; nothing may scroll above it. */
  .view-header { top: 0; margin: 0; }
  /* Attention chips scroll sideways: fade the right edge so a cut chip reads as "more". */
  .attention { margin-inline: calc(-1 * max(16px, env(safe-area-inset-left))); padding-inline: max(16px, env(safe-area-inset-left)); -webkit-mask-image: linear-gradient(90deg, black calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, black calc(100% - 28px), transparent); }
  /* «Дальше» M: the time column takes only what it needs, the meeting title gets the rest. */
  .next-w .w-cols { grid-template-columns: auto minmax(0, 1fr); column-gap: 14px; }
  /* Эпики: short column labels and narrow number columns so epic names fit. */
  .epics-w { --ep-a: 34px; --ep-b: 52px; --ep-c: 38px; }
  .epics-w .lbl-full { display: none; }
  .epics-w .lbl-short { display: inline; }
  .ep-row, .ep-cols { column-gap: 6px; }
  /* Mail boxes: no empty status column when the box is fine. */
  .mail-box:not(.is-problem) { grid-template-columns: minmax(0, 1fr) auto; }
  .mail-box:not(.is-problem) > .row-mark { display: none; }
  /* Last content clears the floating tab bar with breathing room. */
  .view { padding-bottom: calc(var(--tabbar-h) + var(--tabbar-bottom) + 28px); }
  #view:has(> .chat-pane) { padding-bottom: 0; }
}
/* Every content card (screens, calendar, settings, state cards) uses the same glass as widgets. */
.box, .cal-box, .state-card, .set-section { border-color: var(--glass-line); border-radius: var(--r-glass); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--glass-shadow); }
/* Темп трат: progress against the weekly plan with a «today» pace mark, day bars, previous weeks. */
.pace-track { position: relative; height: 6px; margin-top: 6px; border-radius: var(--r-full); background: var(--glass-strong); box-shadow: inset 0 0 0 1px var(--glass-line); }
.pace-fill { display: block; height: 100%; border-radius: inherit; background: var(--accent-grad); }
.pace-fill.is-warn { background: var(--warn); }
.pace-fill.is-danger { background: var(--danger); box-shadow: var(--danger-glow); }
.pace-mark { position: absolute; top: -3px; width: 2px; height: 12px; margin-left: -1px; border-radius: 1px; background: var(--text-1); }
.pace-w .is-ok { color: var(--text-2); }
.pace-w .is-danger { color: var(--danger); }
.pace-chart { display: flex; flex-direction: column; gap: 4px; }
.pace-bars { display: block; width: 100%; height: 48px; overflow: visible; }
.pace-days { display: grid; grid-template-columns: repeat(7, 1fr); color: var(--text-3); font-size: var(--fs-micro); line-height: var(--lh-micro); text-align: center; }
.pace-days .is-today { color: var(--text-1); font-weight: var(--fw-semibold); }
.pace-bars .pb-day { fill: var(--accent-text); opacity: .75; }
.pace-bars .pb-day.is-today { opacity: 1; }
.pace-bars .pb-over { fill: var(--warn); }
.pace-bars .pb-future, .pace-bars .pb-unknown { fill: var(--line-strong); }
.pace-bars .pb-allow { stroke: var(--text-3); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.pace-l { display: flex; flex-direction: column; gap: 10px; }
.pace-weeks-h { margin: 0; color: var(--text-3); font-size: var(--fs-mini); line-height: var(--lh-mini); }
.pace-weeks { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.pace-week { display: grid; grid-template-columns: 48px minmax(0, 1fr) 84px; align-items: center; gap: 8px; color: var(--text-2); font-size: var(--fs-mini); }
.pw-track { height: 5px; border-radius: var(--r-full); background: var(--glass-strong); overflow: hidden; }
.pw-fill { display: block; height: 100%; background: var(--text-3); }
.pw-fill.is-danger { background: var(--danger); }
.pw-sum { text-align: right; }

.cal-back { margin: 0 0 8px; }
.ts-quick { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 4px; }
.ts-quick .button { min-height: 36px; padding: 0 14px; }
