/* Component layer. Ported from design-reference/modernist.css onto the token set in tokens.css.
   Every value here is a var(). If you need one that does not exist, that is a design question —
   ask, do not invent. See CLAUDE.md. */

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

html { background: var(--color-bg); }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-weight: 400;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  margin: 0 0 var(--space-2);
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); }
h4 { font-size: var(--text-h4); }
h5 { font-size: var(--text-h5); }

h6 {
  font-size: var(--text-h6);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

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

/* accent-700/300 rather than the base accent — the base is ~3:1 against the ground, which is
   chrome-and-icons contrast, not body-copy contrast. */
a { color: var(--color-accent-text); text-underline-offset: 3px; }

img { display: block; max-width: 100%; }
figure { margin: 0; }

figcaption {
  font-size: var(--text-xs);
  margin-top: var(--space-1);
  color: var(--muted);
}

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

/* Focus is the accent ring, always. :focus-visible only, so a mouse click does not ring. */
:focus { outline: none; }

:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-accent);
  outline-offset: var(--focus-ring-offset);
}

::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* The interface metadata register — counts, timestamps, ids, paths, status lines, section labels. */
.meta {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--muted);
}

.meta-wide { letter-spacing: var(--tracking-wide); }
.meta-accent { color: var(--color-accent); }

/* — rules — */
.hr {
  height: var(--rule-section);
  border: 0;
  margin: var(--space-4) 0;
  background: var(--color-divider);
}

/* A ruled cell block: the 1px gaps ARE the rules. Not borders, not whitespace. */
.ruled {
  display: grid;
  gap: var(--rule-row);
  background: var(--color-divider);
}

.ruled > * { background: var(--color-bg); }

/* — buttons — */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: var(--text-ui);
  line-height: 1.2;
  color: var(--color-text);
  background: transparent;
  border: var(--rule-row) solid transparent;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: var(--radius-md);
}

.btn svg { display: block; }
.btn:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }

.btn-primary { background: var(--color-accent); color: var(--color-bg); }
.btn-primary:hover { background: var(--color-accent-600); }
.btn-primary:active { background: var(--color-accent-700); }

.btn-secondary { border-color: var(--color-divider); }
.btn-secondary:hover { background: var(--tint-hover); }
.btn-secondary:active { background: var(--tint-pressed); }

.btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
.btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
.btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }

.btn-icon { width: 36px; height: 36px; padding: 0; }

/* Button labels are flush left. */
.btn-block {
  width: 100%;
  margin-top: var(--space-2);
  justify-content: flex-start;
  text-align: left;
}

/* — forms — */
.field > label {
  display: block;
  font-size: 12px;
  margin-bottom: 5px;
  color: var(--muted-strong);
}

.input {
  width: 100%;
  min-height: 36px;
  padding: 6px 10px;
  font: inherit;
  font-size: var(--text-ui);
  color: var(--color-text);
  caret-color: var(--color-accent);
  background: var(--color-surface);
  border: var(--rule-row) solid var(--color-divider);
  border-radius: var(--radius-md);
}

.input:hover { border-color: var(--muted-weak); }
.input:focus-visible { border-color: var(--color-accent); outline-offset: 0; }
textarea.input { min-height: 90px; resize: vertical; }

.radio {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-ui);
}

.radio input,
.seg-opt input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

.radio .dot {
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}

.radio:hover .dot { border-color: var(--color-accent); }

.radio input:checked + .dot {
  border-color: var(--color-accent);
  background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}

.radio input:focus-visible + .dot {
  outline: var(--focus-ring-width) solid var(--color-accent);
  outline-offset: var(--focus-ring-offset);
}

/* — segmented control — */
.seg {
  display: inline-flex;
  overflow: hidden;
  border: var(--rule-row) solid var(--color-divider);
  border-radius: var(--radius-md);
}

.seg-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px var(--space-3);
  font-size: var(--text-sm);
  cursor: pointer;
}

.seg-opt + .seg-opt { border-left: var(--rule-row) solid var(--color-divider); }
.seg-opt:has(input:checked) { background: var(--color-accent); color: var(--color-bg); }
.seg-opt:not(:has(input:checked)):hover { background: var(--tint-hover); }

.seg-opt:has(input:focus-visible) {
  outline: var(--focus-ring-width) solid var(--color-accent);
  outline-offset: calc(var(--focus-ring-offset) * -1);
}

.seg-icon .seg-opt { padding: 5px 9px; }

/* — cards — */
.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.card-kicker {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.card-title {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 17px;
  line-height: 1.2;
}

.card-body { margin: 0; font-size: var(--text-sm); opacity: 0.8; flex: 1; }

.card-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  color: var(--muted);
}

/* Only sheets and drawers are elevated. */
.elev-sm { box-shadow: var(--shadow-sm), var(--edge-hairline); }
.elev-md { box-shadow: var(--shadow-md), var(--edge-hairline); }
.elev-lg { box-shadow: var(--shadow-lg), var(--edge-hairline); }

/* — tags — */
.tag {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  padding: 3px 10px;
  border-radius: var(--radius-sm);
}

.tag-accent { background: var(--color-accent-100); color: var(--color-accent-800); }
.tag-accent-2 { background: var(--color-accent-2-100); color: var(--color-accent-2-800); }
.tag-neutral { background: var(--color-neutral-100); color: var(--color-neutral-800); }
.tag-outline { border: var(--rule-row) solid var(--color-accent); color: var(--color-accent); }
.tag-count { padding: 1px 6px; }

/* — navigation — */
.nav {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--rule-section) solid var(--color-divider);
}

.nav-brand {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 18px;
  margin-right: auto;
}

.nav a { color: inherit; text-decoration: none; font-size: var(--text-ui); }
.nav a:hover,
.nav a[aria-current="page"] { color: var(--color-accent); }

/* — tables — */
.table { width: 100%; border-collapse: collapse; font-size: var(--text-ui); }

.table th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--muted);
  padding: var(--space-2);
  border-bottom: var(--rule-section) solid var(--color-divider);
}

.table td { padding: var(--space-2); border-bottom: var(--rule-row) solid var(--color-divider); }
.table tbody tr:hover { background: var(--tint-row-hover); }

/* — dialog — */
.dialog-backdrop {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}

.dialog {
  width: min(440px, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg), var(--edge-hairline);
}

.dialog-title {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: var(--text-h4);
}

.dialog-body { font-size: var(--text-ui); opacity: 0.85; }

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.grayscale { filter: grayscale(1) contrast(1.08); }

/* Visible to screen readers, not to the eye. For icon-only controls that still need a name. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The router's FocusOnNavigate moves focus to the page heading after navigation, so screen-reader
   and keyboard users land on it. A heading is not an interactive control, and the accent ring is the
   affordance for controls — on an h1 it reads as a rendering artefact. The focus stays where it is;
   only its ring is suppressed. Every interactive element keeps the ring. */
h1:focus-visible,
h2:focus-visible {
  outline: none;
}

/* The framework's error strip. It is hidden until Blazor adds a class to show it — without this rule
   there is no `display: none` and it renders, permanently, on every page. The project template
   supplied these styles; porting off the template dropped them. */
#blazor-error-ui {
  display: none;
  position: fixed;
  inset: auto 0 0 0;
  z-index: 1000;
  padding: var(--space-3) var(--space-4);
  background: var(--color-accent-2-100);
  color: var(--color-accent-2-900);
  border-top: var(--rule-section) solid var(--color-divider);
  box-shadow: var(--shadow-md);
  font-size: var(--text-sm);
}

#blazor-error-ui .reload,
#blazor-error-ui .dismiss {
  margin-left: var(--space-3);
  color: var(--color-accent-2-900);
  cursor: pointer;
  text-underline-offset: 3px;
}

#blazor-error-ui .dismiss {
  float: right;
}

/* Glyph rotations. The chev glyph points left; these turn it without a second glyph in the set. */
.glyph-down { transform: rotate(90deg); }
.glyph-up { transform: rotate(-90deg); }
.glyph-flip { transform: rotate(180deg); }

/* The striped placeholder that stands in for photography. There is no photography in this design —
   every image is this, captioned in mono with what belongs there. */
.placeholder {
  background: repeating-linear-gradient(
    45deg,
    var(--color-neutral-200) 0 6px,
    var(--color-neutral-100) 6px 12px);
  border: var(--rule-row) solid var(--color-divider);
  display: flex;
  align-items: flex-end;
  padding: 10px;
}

.placeholder-photo {
  height: 230px;
}

.placeholder-caption {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  color: var(--color-neutral-700);
  background: var(--color-bg);
  padding: 3px 7px;
}
