/* ==========================================================================
   Stelar Reality — base
   Reset, document defaults, typography, the canonical focus rule,
   the reduced-motion contract and print. No component styling lives here.
   ========================================================================== */

/* --- 1. Reset -------------------------------------------------------------
   Modern-minimal: only the defaults that actively fight a design system. */

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

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

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

/* Replaced elements behave as blocks and never overflow their column. */
img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}
img { height: auto; }

/* Form controls do not inherit typography by default. */
input, button, textarea, select { font: inherit; color: inherit; }

/* A bare <button> is a blank canvas; .btn adds every visual. */
button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* Lists that carry a class are structural, not prose. :where() holds the reset
   at zero specificity so a component can still set its own indent: a bare
   `ol[class]` outranks a single-class rule and silently flattened .timeline's
   24px rail gutter, which pulled every dot outside the card and clipped it. */
:where(ul[class], ol[class]) {
  list-style: none;
  padding: 0;
}

table { border-collapse: collapse; }

body { overflow-wrap: break-word; }

/* --- 2. Document ----------------------------------------------------------- */

body {
  font-family: var(--font-text);
  font-size: var(--type-body-md-size);
  line-height: var(--type-body-lh);
  color: var(--text-primary);
  background-color: var(--surface-primary);
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection {
  background: rgba(189, 92, 23, 0.18);
  color: var(--text-primary);
}

/* --- 3. Headings ------------------------------------------------------------
   Short lines, tight leading, slightly negative tracking. */

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: var(--font-headline);
  font-weight: var(--weight-bold);
  line-height: var(--type-heading-lh);
  letter-spacing: var(--type-heading-ls);
  color: var(--text-primary);
}

h1, .h1 { font-size: var(--type-h1-size); }
h2, .h2 { font-size: var(--type-h2-size); }
h3, .h3 { font-size: var(--type-h3-size); }
h4, .h4 { font-size: var(--type-h4-size); }
h5, .h5 { font-size: var(--type-h5-size); }
h6, .h6 { font-size: var(--type-h6-size); }

.display-1 {
  font-family: var(--font-headline);
  font-size: 4.5rem;
  font-weight: var(--weight-bold);
  line-height: 0.95;
  letter-spacing: -0.035em;
  color: var(--text-primary);
}

/* The cultivated serif carries the *second half* of a message — never a
   whole page of copy. */
.lead {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: var(--weight-regular);
  color: var(--text-secondary);
}

/* --- 4. Prose ---------------------------------------------------------------- */

p { margin-block-end: var(--space-4); }
p:last-child { margin-block-end: 0; }

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

small { font-size: var(--type-body-xs-size); }

code, kbd, samp, pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875em;
}

hr {
  height: 0;
  border: 0;
  border-block-start: var(--border-width) solid var(--border-subtle);
  margin-block: var(--space-5);
  opacity: 1;
}

/* --- 5. Links ----------------------------------------------------------------
   Bare prose links only. Every link-shaped component (.btn, .nav-link,
   .page-link, .menu-item, .sidebar-link, …) resets the underline in its own
   :hover rule. */

a {
  color: var(--text-link);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Links that are chrome rather than prose opt out of the underline. :where()
   keeps this at the same specificity as the rule above, so it wins only by
   source order. .chip-remove matters: it is an anchor wrapping an icon glyph,
   and the prose rule was drawing a line under the ×. */
a:where(.chip, .chip-remove):hover {
  text-decoration: none;
}

/* --- 6. Focus ------------------------------------------------------------------
   THE canonical focus treatment. An outline, never a box-shadow: a shadow
   ring is clipped by `overflow: auto` on the table wrapper and by every
   scroll container, so focused controls inside a scrolled table would lose
   their ring entirely.

   The ring is FLUSH (--focus-offset: 0), not detached. An offset ring is not
   just a ring plus a gap: browsers add the offset to the outline's corner
   radius, so a 2px-radius control gets a 4px-radius ring and the two shapes
   stop reading as concentric — one control looks like two stacked boxes.

   Text fields opt out of the ring entirely and recolour their border instead
   (see .form-control:focus / .form-select:focus). They can, because they own a
   visible 1px border to recolour and a caret that independently says "you are
   here". Buttons and links cannot: .btn-primary's border is already copper, so
   a recolour would be invisible, and .btn-tertiary and prose links have no
   border at all. They keep the ring. */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* Only TEXT-ENTRY controls opt out, and they are named explicitly rather than
   subtracted — `input` covers submit buttons, checkboxes, radios, files and
   colour pickers too, and a blanket exclusion silently strips the ring from
   all of them. That is not hypothetical: the login button is an
   <input type="submit"> whose .btn-primary border is already copper, so it
   would have shown no focus state whatsoever.

   These controls can drop the ring because each owns a 1px border that turns
   copper (.form-control:focus / .form-select:focus) and a caret that says
   "you are here" independently. Anything not listed keeps its ring.
   Same specificity as the rule above (0,1,0) — source order decides. */
:where(
  select,
  textarea,
  input:not([type]),
  input[type="text"],
  input[type="search"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="tel"],
  input[type="url"],
  input[type="date"],
  input[type="datetime-local"],
  input[type="month"],
  input[type="time"],
  input[type="week"]
):focus-visible {
  outline: none;
}

:focus:not(:focus-visible) { outline: none; }

/* --- 7. Reduced motion -------------------------------------------------------
   The ONE sanctioned use of !important in this stylesheet. It has to beat
   every animation and transition declared anywhere downstream — including
   Bootstrap's and any inline style — so specificity alone cannot do the job.
   Motion is not decoration to these users; it is a symptom trigger. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- 8. Print ------------------------------------------------------------------
   Serves the browser's own print command - the app offers no print button.
   Strip the chrome, keep the record. No href-printing rule: these are internal
   URLs with session state and printing them is noise, not context. */

@media print {
  .topbar,
  .sidebar,
  .admin-topbar,
  footer,
  .page-actions,
  .table-actions,
  .flash-stack,
  .pagination,
  .btn { display: none; }

  body {
    background: #FFFFFF;
    color: #000000;
  }

  .card {
    border: 1px solid #000000;
    box-shadow: none;
  }

  tr, img, .card { break-inside: avoid; }
}

summary { cursor: pointer; }
