/* base.css — reset, typography, the application shell, layout utilities.
 * Cascade position: second, after tokens.css.
 * Defines no custom property and no literal colour (SPEC §5.4 rule 1).
 */

/* ── reset ────────────────────────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  min-block-size: 100%;
  /* never transparent: the host paints its own ground behind the page */
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  font-weight: var(--fw-normal);
  /* the page body never scrolls horizontally (§5.3); `clip` keeps sticky working */
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd,
pre {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

img,
svg,
video,
canvas {
  max-inline-size: 100%;
}

svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  inline-size: 1.25em;
  block-size: 1.25em;
  flex: none;
  vertical-align: -0.2em;
}

/* The <symbol> sprite at the top of index.html is a definition, not a picture.
   Without this the rule above gives it a 1.25em line box and every page starts
   ~23px lower. Taken out of flow rather than display:none, which is the form
   <use> is guaranteed to resolve against. */
svg:has(> symbol),
svg:has(> defs) {
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: hidden;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  margin: 0;
}

button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

textarea {
  resize: vertical;
}

fieldset {
  margin: 0;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}

legend {
  padding: 0;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

hr {
  block-size: 1px;
  border: 0;
  margin-block: var(--sp-5);
  background: var(--border);
}

[hidden] {
  display: none !important;
}

::selection {
  background: var(--selection);
  color: var(--text);
}

/* ── focus, once, globally (§5.1) ─────────────────────────────────────────── */

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* on tinted grounds, a halo keeps the ring visible on any surface */
.on-tint:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--bg),
    0 0 0 4px var(--focus);
}

/* ── typography ───────────────────────────────────────────────────────────── */

h1,
h2,
h3,
h4,
h5,
h6 {
  line-height: var(--lh-tight);
  font-weight: var(--fw-semibold);
  text-wrap: balance;
}

h1 {
  font-size: var(--fs-xl);
  letter-spacing: -0.01em;
}

h2 {
  font-size: var(--fs-lg);
}

h3 {
  font-size: var(--fs-md);
}

h4 {
  font-size: var(--fs-base);
}

h5,
h6 {
  font-size: var(--fs-sm);
}

/* The route's <h1 tabindex="-1"> takes focus on every navigation (§7.3.12). It
   is a focus target, not a control: a ring round it after each click says
   nothing. */
h1[tabindex="-1"]:focus {
  outline: none;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--accent-hover);
}

small {
  font-size: var(--fs-sm);
}

strong,
b {
  font-weight: var(--fw-semibold);
}

mark {
  background: var(--mark-bg);
  color: var(--text);
  border-radius: var(--r-sm);
  padding-inline: 2px;
}

code,
kbd,
samp,
pre {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  tab-size: 2;
}

abbr[title] {
  text-decoration: underline dotted;
  cursor: help;
}

/* ── the application shell ────────────────────────────────────────────────
 * Landmarks and BEM aliases are both honoured so the view modules may write
 * either `<nav class="app__rail">` or a bare `<nav>` inside `.app`.
 *   ≥1080  header / rail · thread · inspector
 *   720–1079  header / rail · thread   (inspector lives in a <dialog> drawer)
 *   <720   header / thread             (both live in <dialog> overlays)
 */

.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: var(--header-h) minmax(0, 1fr);
  grid-template-areas:
    "head"
    "main";
  /* a fixed frame, not a minimum: the rail, the thread and the inspector each
     scroll inside their own region, and the page itself never scrolls */
  block-size: 100dvh;
  overflow: hidden;
}

.app__header,
.app > header {
  grid-area: head;
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: var(--header-h);
  padding-inline: var(--sp-4);
  padding-block: 0;
  background: var(--bg);
  border-block-end: 1px solid var(--border);
}

.app__rail,
.app > nav {
  grid-area: rail;
  display: none;
  min-inline-size: 0;
  border-inline-end: 1px solid var(--border);
  background: var(--bg-subtle);
}

/* whatever a view puts here must bring its own scroll container — `.chat` on the
   chat screen, `.scroll-y` anywhere else */
.app__main,
.app > main {
  grid-area: main;
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  min-block-size: 0;
  overflow: hidden;
}

.app__inspector,
.app > aside {
  grid-area: aside;
  display: none;
  min-inline-size: 0;
  border-inline-start: 1px solid var(--border);
  background: var(--bg-subtle);
}

@media (min-width: 720px) {
  .app {
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    grid-template-areas:
      "head head"
      "rail main";
  }

  .app__rail,
  .app > nav {
    display: block;
  }
}

@media (min-width: 1080px) {
  .app {
    grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--inspector-w);
    grid-template-areas:
      "head head head"
      "rail main aside";
  }

  .app__inspector,
  .app > aside {
    display: block;
  }

  /* once collapsed, the inspector gives its column back to the thread. Either
     hook works: the data attribute, or a plain `hidden` on the <aside>. */
  .app[data-inspector="closed"],
  .app:has(> .app__inspector[hidden]),
  .app:has(> aside[hidden]) {
    grid-template-columns: var(--rail-w) minmax(0, 1fr) 0;
  }

  .app[data-inspector="closed"] .app__inspector,
  .app[data-inspector="closed"] > aside {
    display: none;
  }
}

/* the page frame for routes with no rail: /welcome, /signin, /404 */
.page {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  inline-size: 100%;
  max-inline-size: 640px;
  margin-inline: auto;
  padding-inline: var(--sp-4);
  padding-block: var(--sp-6) var(--sp-8);
}

.page--wide {
  max-inline-size: 880px;
}

/* the one headline that carries the product's promise (/welcome, §3.1) */
.hero {
  font-size: var(--fs-2xl);
  line-height: var(--lh-tight);
  letter-spacing: -0.02em;
  max-inline-size: 22ch;
  text-wrap: balance;
}

.hero__sub {
  margin-block-start: var(--sp-3);
  font-size: var(--fs-md);
  line-height: var(--lh-base);
  color: var(--text-muted);
  max-inline-size: 46ch;
}

/* the <noscript> block in the app shell: the only page co-chat can render
   without JavaScript, so it gets the same frame as a real screen */
.noscript {
  inline-size: 100%;
  max-inline-size: 560px;
  margin-inline: auto;
  padding-inline: var(--sp-4);
  padding-block: var(--sp-8);
}

.noscript h1 {
  margin-block-end: var(--sp-4);
}

.noscript p {
  margin-block-end: var(--sp-3);
  color: var(--text-muted);
  max-inline-size: 62ch;
  line-height: var(--lh-prose);
}

.noscript code {
  padding: 1px var(--sp-1);
  border: 1px solid var(--code-border);
  border-radius: var(--r-sm);
  background: var(--code-bg);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: var(--fw-semibold);
  color: var(--text);
  text-decoration: none;
}

.brand__mark {
  color: var(--accent);
}

.skip {
  position: absolute;
  inset-inline-start: var(--sp-2);
  inset-block-start: -100%;
  z-index: var(--z-toast);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  box-shadow: var(--sh-2);
}

.skip:focus {
  inset-block-start: var(--sp-2);
}

/* ── utilities ────────────────────────────────────────────────────────────── */

/* visually hidden, still announced and still focusable when it must be */
.vh {
  position: absolute !important;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* …revealed on focus only when it is a control: revealing the chat screen's
   hidden route <h1> pushed the thread down 31 px until the next Tab. */
a.vh:focus-visible,
button.vh:focus-visible {
  position: static !important;
  inline-size: auto;
  block-size: auto;
  margin: 0;
  overflow: visible;
  clip-path: none;
  white-space: normal;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  min-inline-size: 0;
}

.stack--tight {
  gap: var(--sp-2);
}

.stack--loose {
  gap: var(--sp-6);
}

.row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-inline-size: 0;
}

.row--wrap {
  flex-wrap: wrap;
}

.row--between {
  justify-content: space-between;
}

.row--end {
  justify-content: flex-end;
}

.row--top {
  align-items: flex-start;
}

.grow {
  flex: 1 1 auto;
  min-inline-size: 0;
}

.measure {
  max-inline-size: var(--measure);
}

.center {
  margin-inline: auto;
}

/* a scrolling region inside a fixed frame (`.app__main`, a drawer, a panel) */
.scroll-y {
  flex: 1 1 auto;
  min-block-size: 0;
  overflow-y: auto;
  overscroll-behavior-y: contain;
}

/* the ONLY places allowed to scroll sideways (§5.3) */
.scroll-x {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  max-inline-size: 100%;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-inline-size: 0;
}

.nowrap {
  white-space: nowrap;
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

.caps {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

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

.faint {
  color: var(--text-faint);
  font-size: var(--fs-sm);
}

.sep {
  color: var(--text-faint);
  padding-inline: var(--sp-1);
}

/* scrollbars: tinted, never invisible. `scrollbar-color` inherits, so it is set
   once; `scrollbar-width` does not, so it is not. */
:root {
  scrollbar-color: var(--border-strong) transparent;
}

* {
  scrollbar-width: thin;
}
