/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* min-height, not height: a fixed height:100% caps body at exactly one
   viewport tall, which breaks position:sticky sidebars on any page whose
   content grows taller than the viewport (the sticky element's containing
   block never grows to give it room to stick). min-height still lets short
   pages (auth screens, etc.) fill the viewport for centering. */
html, body { min-height: 100%; }
body {
  font-family: var(--font-sans);
  background: hsl(var(--bg));
  color: hsl(var(--fg));
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* cv11 = single-storey 'a' at small sizes, ss01 = open digits; both make
     dense UI text noticeably easier to scan. tnum keeps every number column
     aligned without having to remember .tabular everywhere. */
  font-feature-settings: "cv11", "ss01";
  text-rendering: optimizeLegibility;
}
img, picture { display: block; max-width: 100%; }
svg { width: 20px; height: 20px; flex-shrink: 0; display: inline-block; vertical-align: middle; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
table { border-collapse: collapse; width: 100%; }

::selection { background-color: hsl(var(--primary) / 0.22); color: hsl(var(--fg)); }

/* Only while the toggle is being used — see shell.js. Transitioning colours
   permanently would make every hover feel laggy. */
html.theme-transition, html.theme-transition *, html.theme-transition *::before, html.theme-transition *::after {
  transition: background-color 220ms var(--ease-out), border-color 220ms var(--ease-out),
              color 220ms var(--ease-out), fill 220ms var(--ease-out) !important;
}

:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: hsl(var(--border-strong)); border-radius: var(--radius-full); border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: hsl(var(--fg-subtle)); background-clip: content-box; }

/* ---------- Typography ---------- */
/* One scale, applied by element AND by utility so a heading and a styled div
   can never drift apart. Tracking tightens as size grows — Inter is drawn
   loose at display sizes and looks amateurish left at 0. */
h1, h2, h3, h4, h5 { font-weight: 700; line-height: var(--leading-tight); text-wrap: balance; }
h1 { font-size: 28px; letter-spacing: var(--tracking-tight); }
h2 { font-size: var(--text-xl); letter-spacing: var(--tracking-tight); }
h3 { font-size: var(--text-lg); letter-spacing: var(--tracking-snug); }
h4 { font-size: 14px; letter-spacing: var(--tracking-snug); }
h5 { font-size: var(--text-sm); letter-spacing: var(--tracking-snug); }
p { text-wrap: pretty; }
/* File names, URLs and wifi keys have no break points; without this one long
   token widens the whole page on a phone. Only breaks when nothing else fits. */
p, li, dd, td, h1, h2, h3, h4, label { overflow-wrap: break-word; }

.text-3xs { font-size: var(--text-3xs); }
.text-2xs { font-size: var(--text-2xs); }
.text-xs { font-size: var(--text-xs); }
.text-sm { font-size: var(--text-sm); }
.text-ui { font-size: var(--text-ui); }
.text-base { font-size: var(--text-base); }
.text-lg { font-size: var(--text-lg); letter-spacing: var(--tracking-snug); }
.text-xl { font-size: var(--text-xl); letter-spacing: var(--tracking-tight); }
.text-2xl { font-size: var(--text-2xl); letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); }
.text-3xl { font-size: var(--text-3xl); letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); }
.text-4xl { font-size: var(--text-4xl); letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); }
.font-medium { font-weight: 500; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.font-extrabold { font-weight: 800; }

/* The single small-caps label style for the whole app. Every page had been
   hand-rolling its own `font-size:11px; text-transform:uppercase;
   letter-spacing:.05em` with slightly different numbers. */
.eyebrow {
  font-size: var(--text-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: var(--tracking-caps); color: hsl(var(--fg-muted));
}
/* Numbers that sit in a column, get compared, or change in place. Lining +
   tabular figures stop the layout twitching as values update. */
.num { font-variant-numeric: tabular-nums lining-nums; }
.text-muted { color: hsl(var(--fg-muted)); }
.text-subtle { color: hsl(var(--fg-subtle)); }
.text-primary { color: hsl(var(--primary)); }
.text-accent { color: hsl(var(--accent-soft-fg)); }   /* --accent is tuned for white ON it; as text it reads 4.22:1 */
.text-destructive { color: hsl(var(--destructive)); }
.text-success { color: hsl(var(--success)); }
.tabular { font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Multi-line clamp — several pages had their own -webkit-box stack. */
.clamp-2, .clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.clamp-2 { -webkit-line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; }
/* Measure. Long-form text past ~70 characters is measurably harder to read. */
.prose { max-width: 68ch; line-height: var(--leading-relaxed); }

/* ---------- Layout utilities ---------- */
.container {
  max-width: var(--content-max); margin-inline: auto;
  padding-left: calc(var(--space-6) + env(safe-area-inset-left));
  padding-right: calc(var(--space-6) + env(safe-area-inset-right));
}
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
/* A skip link is only useful if a sighted keyboard user can SEE it once it
   takes focus — .visually-hidden alone clips it permanently, which made the
   link in base.html/base_cleaner.html unusable. :focus-visible un-clips it
   into a real, positioned control. */
a.visually-hidden:focus-visible {
  position: fixed; top: var(--space-3); left: var(--space-3); z-index: 300;
  width: auto; height: auto; margin: 0; clip: auto; overflow: visible;
  padding: 10px var(--space-4); border-radius: var(--radius-md);
  background: hsl(var(--surface)); color: hsl(var(--fg));
  font-size: 13.5px; font-weight: 600; box-shadow: var(--shadow-popover);
}
/* The skip link points at #main. Without tabindex the browser moves focus
   nowhere on some engines; without scroll-margin the sticky topbar covers the
   landing point. Both are set here so every page inherits the behaviour. */
#main { scroll-margin-top: calc(var(--topbar-h) + var(--space-4)); }
#main:focus { outline: none; }
#main:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 4px; }

.flex { display: flex; }
.inline-flex { display: inline-flex; }
.whitespace-nowrap { white-space: nowrap; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-center { justify-content: center; }
.flex-wrap { flex-wrap: wrap; }
.flex-1 { flex: 1 1 0%; }
.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-5 { gap: var(--space-5); }
.gap-6 { gap: var(--space-6); }
.gap-8 { gap: var(--space-8); }
.ml-auto { margin-left: auto; }
.w-full { width: 100%; }
.relative { position: relative; }
.items-end { align-items: flex-end; }
.justify-end { justify-content: flex-end; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.grid { display: grid; }
.hidden { display: none !important; }
/* Not in the source template — without this, the `hidden` ATTRIBUTE (as
   opposed to the .hidden class above) loses to any class on the same element
   that sets its own `display` (e.g. .btn's `display: inline-flex`), since
   author rules always beat the browser's default [hidden]{display:none} UA
   rule. Every `el.hidden = true/false` toggle across the app's JS relies on
   this — drawers, modals, settings sub-panels, the split/combined toggle. */
[hidden] { display: none !important; }
.w-3.h-3, svg.w-3 { width: 12px; height: 12px; }
.w-4.h-4, svg.w-4 { width: 16px; height: 16px; }

@media (max-width: 768px) {
  .container {
    padding-left: calc(var(--space-4) + env(safe-area-inset-left));
    padding-right: calc(var(--space-4) + env(safe-area-inset-right));
  }
  .md\:hidden { display: none !important; }
}
@media (min-width: 769px) {
  .desktop\:hidden { display: none !important; }
}

.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }

/* Grid/flex items default to a min-content minimum width, which lets long
   text force these two-column page layouts wider than their container and
   create horizontal scroll on narrow viewports. min-width:0 lets the item
   shrink and rely on normal text wrapping/ellipsis instead. Safe to apply
   broadly — it only permits shrinking, never forces it. */
.dash-grid > *, .detail-grid > *, .gi-grid > *, .thread-grid > *, .acct-grid > *,
.settings-grid > *, .conflict-compare > *, .kpi-row > *, .stats-grid > *,
.summary-grid > *, .steps > *, .feature-grid > *, .field-row > *, .apt-grid > *, .tv-grid > * {
  min-width: 0;
}

.fade-in { animation: fadeIn var(--dur-base) var(--ease-out) both; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.slide-up { animation: slideUp var(--dur-base) var(--ease-out) both; }
@keyframes slideUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

/* Links found inside owner-written text (see forms.js). */
.linkify a {
  color: hsl(var(--primary)); font-weight: 600; text-decoration: underline;
  text-decoration-color: hsl(var(--primary) / .4); text-underline-offset: 2px; overflow-wrap: anywhere;
}
@media (hover: hover) and (pointer: fine) { .linkify a:hover { text-decoration-color: currentColor; } }
/* A walkthrough video link, shown as a button rather than a raw address. */
.linkify a.link-video {
  display: inline-flex; align-items: center; gap: var(--space-1-5); margin: var(--space-1) 0;
  padding: var(--space-1-5) var(--space-3); border-radius: var(--radius-full);
  background: hsl(var(--primary-soft)); color: hsl(var(--primary-soft-fg));
  font-size: var(--text-sm); font-weight: 700; text-decoration: none; white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.linkify a.link-video svg { width: var(--space-3-5); height: var(--space-3-5); }
.linkify a.link-video:active { transform: scale(.97); }
@media (hover: hover) and (pointer: fine) { .linkify a.link-video:hover { background: hsl(var(--primary) / .18); } }
