/* ==========================================================================
   components.css - reusable interface pieces.

   Naming: .block, .block__element, .block--modifier
   Every value references a token from variables.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Wordmark
   -------------------------------------------------------------------------- */

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wordmark);
  text-transform: uppercase;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
}

.wordmark::after {
  content: "";
  inline-size: 5px;
  block-size: 5px;
  background-color: var(--color-accent);
  border-radius: 1px;
  transform: translateY(-0.35em);
  transition: transform var(--duration) var(--ease-out);
}

.wordmark:hover::after {
  transform: translateY(-0.35em) scale(1.5);
}

/* --------------------------------------------------------------------------
   Site header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  background-color: color-mix(in srgb, var(--color-bg) 82%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-block-end: var(--border-width) solid transparent;
  transition: border-color var(--duration) var(--ease-out),
    background-color var(--duration) var(--ease-out);
}

/* Applied by main.js once the page is scrolled. */
.site-header.is-scrolled {
  border-block-end-color: var(--color-border);
  background-color: color-mix(in srgb, var(--color-bg) 94%, transparent);
  box-shadow: var(--shadow-sm);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  min-block-size: var(--header-height);
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* The header CTA is desktop-only; the mobile panel carries its own copy
   (.nav__cta) so the narrow header stays down to wordmark + toggle.
   Scoped to the parent so it outranks .btn's own display, which is
   declared further down this file. */
.site-header__actions .site-header__cta {
  display: none;
}

/* --------------------------------------------------------------------------
   Primary navigation
   Mobile: full-height panel toggled by .nav-toggle.
   Desktop rules live in responsive.css.
   -------------------------------------------------------------------------- */

.nav {
  position: fixed;
  inset-block-start: var(--header-height);
  inset-inline: 0;
  block-size: calc(100dvh - var(--header-height));
  z-index: var(--z-nav-panel);
  background-color: var(--color-bg);
  border-block-start: var(--border-width) solid var(--color-border);
  box-shadow: var(--shadow-lg);
  padding: var(--space-lg) var(--container-pad) var(--space-2xl);
  overflow-y: auto;
  /* visibility (not display) keeps links out of the tab order when closed
     while still allowing the panel to animate. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity var(--duration) var(--ease-out),
    transform var(--duration) var(--ease-out),
    visibility 0s linear var(--duration);
}

.nav.is-open {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

.nav__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  max-width: var(--container-width);
  margin-inline: auto;
}

.nav__link {
  display: block;
  padding-block: var(--space-xs);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-secondary);
  text-decoration: none;
  border-block-end: var(--border-width) solid var(--color-border);
  transition: color var(--duration-fast) var(--ease-out);
}

.nav__link:hover {
  color: var(--color-text);
}

.nav__link[aria-current="page"] {
  color: var(--color-text);
}

/* Commerce CTA inside the open mobile panel. */
.nav__cta {
  display: inline-flex;
  margin-block-start: var(--space-lg);
}

.nav__footer {
  max-width: var(--container-width);
  margin: var(--space-lg) auto 0;
}

/* Hamburger / close button. Hidden at desktop widths. */
.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  inline-size: 44px;
  block-size: 44px;
  margin-inline-end: -10px;
  padding-inline: 10px;
  border-radius: var(--radius-sm);
  color: var(--color-text);
}

.nav-toggle__bar {
  display: block;
  inline-size: 22px;
  block-size: 1.5px;
  background-color: currentColor;
  transition: transform var(--duration) var(--ease-out),
    opacity var(--duration-fast) var(--ease-out);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 0.7rem 1.35rem;
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-weight: var(--weight-semibold);
}

.btn--primary:hover {
  background-color: var(--color-accent-bright);
}

.btn--secondary {
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.btn--secondary:hover {
  border-color: var(--color-accent);
  color: var(--color-accent-bright);
  background-color: var(--color-accent-soft);
}

/* Commerce variant - money or engagement only. See --color-commerce. */
.btn--commerce {
  background-color: var(--color-commerce);
  color: var(--color-on-commerce);
  font-weight: var(--weight-semibold);
}

.btn--commerce:hover {
  background-color: var(--color-commerce-bright);
}

/* Outlined commerce button, for use on top of a coral-tinted panel. */
.btn--commerce-outline {
  border-color: var(--color-commerce-line);
  color: var(--color-commerce);
}

.btn--commerce-outline:hover {
  border-color: var(--color-commerce);
  background-color: var(--color-commerce-soft);
  color: var(--color-commerce-bright);
}

.btn--ghost {
  padding-inline: 0;
  color: var(--color-text);
}

.btn--ghost:hover {
  color: var(--color-accent-bright);
}

/* Compact button sitting in the site header. */
.btn--sm {
  padding: 0.45rem 0.9rem;
  font-size: var(--text-xs);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

/* Arrow that nudges on hover. */
.btn__arrow {
  transition: transform var(--duration) var(--ease-out);
}

.btn:hover .btn__arrow {
  transform: translateX(3px);
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-md);
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--duration) var(--ease-out),
    background-color var(--duration) var(--ease-out),
    transform var(--duration) var(--ease-out);
}

.card__title {
  margin: 0;
  color: var(--color-text);
}

.card__body {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.card__index {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Discipline split - the two-path block on the homepage
   -------------------------------------------------------------------------- */

.discipline {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-lg);
  min-block-size: 340px;
  padding: var(--space-md);
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--duration) var(--ease-out),
    background-color var(--duration) var(--ease-out);
}

.discipline::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 2px;
  background-color: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-slow) var(--ease-out);
}

.discipline:hover {
  border-color: var(--color-border-strong);
  background-color: var(--color-surface-hover);
}

.discipline:hover::before,
.discipline:focus-within::before {
  transform: scaleX(1);
}

.discipline__title {
  font-size: clamp(1.75rem, 1.4rem + 1.4vw, 2.25rem);
  margin-block: var(--space-xs) 0;
}

.discipline__body {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
}

.discipline__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding-block-start: var(--space-sm);
  border-block-start: var(--border-width) solid var(--color-border);
}

.discipline__link {
  text-decoration: none;
  color: var(--color-text);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
}

.discipline__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.discipline__link:hover {
  color: var(--color-accent-bright);
}

/* --------------------------------------------------------------------------
   Tags and badges
   -------------------------------------------------------------------------- */

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-2xs);
}

.tag-list--spaced {
  margin-block-start: var(--space-md);
}

.tag {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-pill);
  background-color: rgba(255, 255, 255, 0.02);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}

.tag--accent {
  border-color: var(--color-accent-line);
  background-color: var(--color-accent-soft);
  color: var(--color-accent);
}

/* Tags that are links. Reads as a button, not underlined blue text. */
a.tag {
  text-decoration: none;
  transition: border-color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

a.tag:hover {
  border-color: var(--color-accent);
  background-color: var(--color-accent-soft);
  color: var(--color-accent-bright);
  transform: translateY(-1px);
}

/* Slightly larger pills, for when they are the content rather than metadata. */
.tag-list--lg .tag {
  padding: 0.45rem 0.95rem;
  font-size: var(--text-sm);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-sm);
  background-color: var(--color-accent-soft);
  border: var(--border-width) solid var(--color-accent-line);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-accent);
}

.badge--neutral {
  background-color: rgba(255, 255, 255, 0.04);
  border-color: var(--color-border);
  color: var(--color-muted);
}

.badge--commerce {
  background-color: var(--color-commerce-soft);
  border-color: var(--color-commerce-line);
  color: var(--color-commerce);
}

/* Service panel on /work-with-me/ - a card with a commerce-tinted edge. */
.service {
  border-color: var(--color-border-strong);
}

.service__price {
  margin-block-start: auto;
  padding-block-start: var(--space-sm);
  border-block-start: var(--border-width) solid var(--color-border);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-commerce);
}

/* What a service covers, listed at the foot of its card. The marker is a
   drawn rule rather than a glyph so it never gets announced as text.

   The class is doubled deliberately. This is a <ul>, and reset.css zeroes
   margin and padding on ul[class] at specificity (0,1,1), which outranks a
   single class. Doubling reaches (0,2,0) without !important, so the auto
   margin that pins the list to the bottom of the card actually applies. */
.feature-list.feature-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  margin-block-start: auto;
  padding-block-start: var(--space-sm);
  border-block-start: var(--border-width) solid var(--color-border);
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.feature-list li {
  display: flex;
  gap: var(--space-2xs);
}

.feature-list li::before {
  content: "";
  flex: none;
  inline-size: 6px;
  block-size: 1px;
  margin-block-start: 0.7em;
  background-color: var(--color-accent);
}

/* Small status dot used in the "current focus" list. */
.status-dot {
  inline-size: 6px;
  block-size: 6px;
  border-radius: 50%;
  background-color: var(--color-accent);
  flex: none;
}

/* --------------------------------------------------------------------------
   Stats
   -------------------------------------------------------------------------- */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-md);
}

.stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding-inline-start: var(--space-sm);
  border-inline-start: 2px solid var(--color-accent-line);
}

.stat__value {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  line-height: 1.1;
  color: var(--color-text);
}

/* Unit suffix inside a stat value, e.g. the "cc" in 649cc. */
.stat__unit {
  font-size: 0.5em;
  font-weight: var(--weight-medium);
  letter-spacing: 0;
  margin-inline-start: 0.08em;
  color: var(--color-muted);
}

.stat__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Status grid - the same idea as .stat, but for words instead of figures.

   .stat sets its value at display size because a number reads fine that
   large. A phrase like "Men's Physique" does not, so this keeps the value
   near body size and lets the mono label carry the structure.
   -------------------------------------------------------------------------- */

.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-md);
}

.status {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding-inline-start: var(--space-sm);
  border-inline-start: 2px solid var(--color-accent-line);
}

.status__label {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

.status__value {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-normal);
  line-height: var(--leading-snug);
  color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Rotation - an ordered sequence shown inline, e.g. the training split.
   Wraps rather than scrolls, so it survives a 320px viewport.
   -------------------------------------------------------------------------- */

.rotation {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.rotation li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

/* Decorative separator only. The list is ordered, so the sequence is
   already carried by the markup. */
.rotation li:not(:last-child)::after {
  content: "\2192";
  color: var(--color-accent);
}

/* --------------------------------------------------------------------------
   Entry - used for capabilities, projects and focus items
   -------------------------------------------------------------------------- */

.entry-list {
  display: flex;
  flex-direction: column;
  border-block-start: var(--border-width) solid var(--color-border);
}

.entry {
  display: grid;
  gap: var(--space-2xs) var(--space-lg);
  padding-block: var(--space-md);
  border-block-end: var(--border-width) solid var(--color-border);
  transition: background-color var(--duration) var(--ease-out);
}

.entry__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.entry__title {
  margin: 0;
  color: var(--color-text);
}

.entry__body {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.entry__body + .entry__body {
  margin-block-start: var(--space-2xs);
}

.entry__main > * + * {
  margin-block-start: var(--space-xs);
}

/* --------------------------------------------------------------------------
   Platform groups - grouped tag lists on the technology page
   -------------------------------------------------------------------------- */

.platform-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-md);
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
}

.platform-group__title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-accent);
}

/* --------------------------------------------------------------------------
   Media containers
   Placeholders keep their aspect ratio so replacing them with a real
   <img> does not shift the layout.
   -------------------------------------------------------------------------- */

.media {
  position: relative;
  overflow: hidden;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-bg-elevated);
}

.media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.media--portrait {
  aspect-ratio: 4 / 5;
}

.media--square {
  aspect-ratio: 1 / 1;
}

.media--landscape {
  aspect-ratio: 3 / 2;
}

.media--wide {
  aspect-ratio: 16 / 9;
}

/* A <video> fills its container the same way an <img> does. */
.media video {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  background-color: #000;
}

/* The empty state shown until a real photograph is dropped in. */
.media__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3xs);
  padding: var(--space-sm);
  text-align: center;
  background-image: repeating-linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.022) 0,
    rgba(255, 255, 255, 0.022) 1px,
    transparent 1px,
    transparent 9px
  );
}

.media__placeholder-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-muted);
}

.media__placeholder-hint {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-muted);
  overflow-wrap: anywhere;
}

.media__caption {
  margin-block-start: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Call to action block
   -------------------------------------------------------------------------- */

.cta {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: clamp(1.5rem, 4vw, 3rem);
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
}

.cta__title {
  margin: 0;
  max-width: 22ch;
}

.cta__body {
  color: var(--color-text-secondary);
}

.cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

/* Commerce CTA - the one on /work-with-me/ and the hire prompts. */
.cta--commerce {
  border-color: var(--color-commerce-line);
  background-color: var(--color-commerce-soft);
}

.cta--commerce .eyebrow {
  color: var(--color-commerce);
}

.cta--commerce .eyebrow::before {
  background-color: var(--color-commerce-line);
}

/* --------------------------------------------------------------------------
   Statement - one line that carries a section on its own.
   -------------------------------------------------------------------------- */

.statement {
  padding: clamp(1.5rem, 4vw, 2.75rem);
  border: var(--border-width) solid var(--color-accent-line);
  border-radius: var(--radius-lg);
  background-color: var(--color-accent-soft);
}

.statement__text {
  margin: 0;
  max-width: 26ch;
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 1.1rem + 1.2vw, 2rem);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-snug);
  color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Notice - informational panel (e.g. "backend not yet configured")
   -------------------------------------------------------------------------- */

.notice {
  display: flex;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: var(--border-width) solid var(--color-accent-line);
  border-inline-start-width: 2px;
  border-radius: var(--radius-sm);
  background-color: var(--color-accent-soft);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.notice p {
  margin: 0;
  max-width: none;
}

.notice__title {
  display: block;
  margin-block-end: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-accent);
}

/* For text that has to be present but should not raise an alarm, such as
   the scope note on nutrition coaching. Same shape, no accent tint. */
.notice--quiet {
  border-color: var(--color-border-strong);
  background-color: rgba(255, 255, 255, 0.015);
}

.notice--quiet .notice__title {
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.field__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

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

.field__hint {
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.field__control {
  inline-size: 100%;
  padding: 0.7rem 0.85rem;
  background-color: var(--color-bg-elevated);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--text-body);
  transition: border-color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
}

.field__control::placeholder {
  color: var(--color-muted);
}

.field__control:hover {
  border-color: var(--color-accent-line);
}

.field__control:focus {
  border-color: var(--color-accent);
  background-color: var(--color-surface);
}

/* Native select arrow is inconsistent across platforms; draw our own. */
select.field__control {
  appearance: none;
  padding-inline-end: 2.25rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-muted) 50%),
    linear-gradient(135deg, var(--color-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 1px),
    calc(100% - 13px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.field__error {
  display: none;
  font-size: var(--text-xs);
  color: var(--color-danger);
}

.field.has-error .field__control {
  border-color: var(--color-danger);
}

.field.has-error .field__error {
  display: block;
}

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

/* Live region for the form-level result message. */
.form__status {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.form__status:empty {
  display: none;
}

.form__status[data-state="error"] {
  color: var(--color-danger);
}

.form__status[data-state="success"] {
  color: var(--color-success);
}

/* Honeypot - hidden from humans, tempting to naive bots. */
.form__trap {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Definition rows - label/value pairs
   -------------------------------------------------------------------------- */

.def-list {
  display: grid;
  gap: 0;
  margin: 0;
  border-block-start: var(--border-width) solid var(--color-border);
}

.def-list__row {
  display: grid;
  gap: var(--space-3xs) var(--space-md);
  padding-block: var(--space-sm);
  border-block-end: var(--border-width) solid var(--color-border);
}

.def-list__term {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-muted);
}

.def-list__desc {
  margin: 0;
  color: var(--color-text);
  font-size: var(--text-sm);
}

/* Compact variant for def-lists nested inside a panel that already
   provides the framing. Stays single-column at every width, because the
   panels are too narrow for a label/value split. */
.def-list--compact {
  border-block-start: 0;
}

.def-list--compact .def-list__row {
  grid-template-columns: 1fr;
  padding-block: var(--space-2xs);
}

.def-list--compact .def-list__row:last-child {
  padding-block-end: 0;
  border-block-end: 0;
}

/* --------------------------------------------------------------------------
   Data table - progress log and any future tabular content.
   Always wrap in .table-scroll so narrow screens scroll the table, never
   the page.
   -------------------------------------------------------------------------- */

.table-scroll {
  overflow-x: auto;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
}

.data-table {
  min-inline-size: 34rem;
  font-size: var(--text-sm);
}

.data-table caption {
  padding: var(--space-sm) var(--space-md);
  text-align: start;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-muted);
  border-block-end: var(--border-width) solid var(--color-border);
}

.data-table th,
.data-table td {
  padding: var(--space-xs) var(--space-md);
  text-align: start;
  border-block-end: var(--border-width) solid var(--color-border);
}

.data-table tbody tr:last-child th,
.data-table tbody tr:last-child td {
  border-block-end: 0;
}

.data-table thead th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-muted);
  background-color: rgba(255, 255, 255, 0.02);
}

.data-table td {
  color: var(--color-text);
}

.data-table__empty {
  padding-block: var(--space-lg);
  color: var(--color-muted);
  font-style: italic;
}

/* --------------------------------------------------------------------------
   Fact cards - a straight figure with the real answer underneath
   -------------------------------------------------------------------------- */

.fact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--space-sm);
}

.fact {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-md);
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
}

.fact__title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-accent);
}

.fact__body {
  margin: 0;
  max-width: none;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text-secondary);
}

/* Citation, present but quiet. */
.fact__source {
  margin-block-start: auto;
  padding-block-start: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--color-muted);
  text-decoration: none;
}

.fact__source:hover {
  color: var(--color-accent-bright);
}

/* The one card that is not a fact about the city. */
.fact--personal {
  border-color: var(--color-accent-line);
  background-color: var(--color-accent-soft);
}

.fact--personal .fact__body {
  color: var(--color-text);
}

/* Understated outbound link, used for her profile. */
.link-out {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
}

.link-out:hover {
  color: var(--color-accent-bright);
}

/* --------------------------------------------------------------------------
   Poems and quiet asides
   -------------------------------------------------------------------------- */

.poem {
  max-width: 44ch;
  padding-inline-start: var(--space-md);
  border-inline-start: 2px solid var(--color-accent-line);
}

.poem__title {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-accent);
}

.poem p {
  margin: 0;
  max-width: none;
  line-height: 1.85;
  color: var(--color-text-secondary);
}

.poem p + p {
  margin-block-start: var(--space-sm);
}

.poem strong {
  color: var(--color-text);
  font-weight: var(--weight-regular);
}

/* One-line jabs dropped between sections. */
.aside-line {
  padding-block: var(--space-lg);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  line-height: 1.7;
  color: var(--color-muted);
  max-width: 52ch;
  margin-inline: auto;
}

.aside-line em {
  color: var(--color-accent);
  font-style: normal;
}

/* Something you have to open. Native <details>, so no JavaScript. */
.reveal {
  border: var(--border-width) dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
}

.reveal > summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent);
  list-style: none;
}

.reveal > summary::-webkit-details-marker {
  display: none;
}

.reveal > summary:hover {
  color: var(--color-accent-bright);
}

.reveal[open] > summary {
  margin-block-end: var(--space-sm);
}

.reveal p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* Bottom-of-page line, for whoever scrolls that far. */
.secret {
  margin-block-start: var(--space-lg);
  font-size: var(--text-sm);
  font-style: italic;
  line-height: 1.7;
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Audio track
   Native <audio> controls are deliberately left unstyled: they are keyboard
   accessible, familiar, and behave correctly on mobile. Only the container
   around them is styled.
   -------------------------------------------------------------------------- */

.track {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-md);
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
}

.track__artist {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-accent);
}

.track__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
}

.track audio {
  inline-size: 100%;
  margin-block-start: var(--space-xs);
}

/* --------------------------------------------------------------------------
   Breadcrumb - sub-pages under a hub
   -------------------------------------------------------------------------- */

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-muted);
}

.breadcrumb__list li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
}

.breadcrumb__list li:not(:last-child)::after {
  content: "/";
  color: var(--color-accent);
}

.breadcrumb__list a {
  color: var(--color-muted);
  text-decoration: none;
}

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

.breadcrumb__list [aria-current="page"] {
  color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Social links
   -------------------------------------------------------------------------- */

.social-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-block-start: var(--space-md);
}

.social-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  text-decoration: none;
}

.social-link:hover {
  color: var(--color-accent-bright);
}

.social-link__icon {
  flex: none;
  color: var(--color-accent);
  transition: color var(--duration-fast) var(--ease-out);
}

.social-link:hover .social-link__icon {
  color: inherit;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  padding-block: var(--space-xl) var(--space-lg);
  border-block-start: var(--border-width) solid var(--color-border);
  background-color: var(--color-bg-elevated);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-lg);
  margin-block-end: var(--space-lg);
}

.site-footer__tagline {
  margin-block-start: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
  max-width: 34ch;
}

.footer-nav__title {
  margin-block-end: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

.footer-nav__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.footer-nav__link {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  text-decoration: none;
}

/* Only real links react - the "Focus" column is plain text. */
a.footer-nav__link:hover {
  color: var(--color-accent-bright);
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding-block-start: var(--space-md);
  border-block-start: var(--border-width) solid var(--color-border);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  padding-block: clamp(4rem, 12vh, 8rem) var(--space-section);
  overflow: hidden;
}

/* Very restrained backdrop: one soft radial wash, no animation. */
.hero::before {
  content: "";
  position: absolute;
  inset-block-start: -30%;
  inset-inline-start: 50%;
  inline-size: min(1100px, 130vw);
  aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(
    circle,
    var(--color-accent-wash) 0%,
    color-mix(in srgb, var(--color-accent) 2%, transparent) 38%,
    transparent 68%
  );
  pointer-events: none;
}

.hero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  width: 100%;
}

/* Secondary line inside the hero heading. */
.hero__name {
  display: block;
  margin-block-start: var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

.hero__title {
  margin: 0;
}

/* Statement lines in the homepage hero. Stacked on narrow screens; the
   dot separators only appear once the three words fit on one line
   (see responsive.css). */
.hero__statement {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1rem + 0.8vw, 1.5rem);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
}

.hero__statement li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-md);
}

.hero__statement li:not(:last-child)::after {
  content: "";
  inline-size: 4px;
  block-size: 4px;
  border-radius: 50%;
  background-color: var(--color-accent);
  display: none;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-block-start: var(--space-2xs);
}

/* Page heroes on interior pages: shorter, with a divider. */
.page-hero {
  padding-block: clamp(3rem, 9vh, 5.5rem) clamp(2rem, 5vw, 3.5rem);
  border-block-end: var(--border-width) solid var(--color-border);
}

.page-hero__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.page-hero__inner .stat-row {
  margin-block-start: var(--space-md);
}

.page-hero__title {
  margin: 0;
  max-width: 18ch;
}

.page-hero__intro {
  max-width: var(--measure);
}

/* --------------------------------------------------------------------------
   Gallery
   -------------------------------------------------------------------------- */

.gallery {
  display: grid;
  gap: var(--space-sm);
}

.gallery__item {
  margin: 0;
}

/* Masonry variant for mixed portrait/landscape sets. CSS columns give real
   masonry with no JavaScript, and because nothing is forced to a fixed
   aspect ratio, no photograph gets cropped. Column counts are set in
   responsive.css. */
.gallery--masonry {
  display: block;
  column-gap: var(--space-sm);
}

.gallery--masonry .gallery__item {
  break-inside: avoid;
  margin-block-end: var(--space-sm);
}

/* Media box with no enforced aspect ratio - the image sets its own. */
.media--natural {
  aspect-ratio: auto;
}

.media--natural img {
  block-size: auto;
  object-fit: fill;
}

/* --------------------------------------------------------------------------
   Check-in - a dated progress entry: metadata, three views, notes.

   Currently unused. It exists so that the physique progress record can be
   switched on by pasting markup, without the page needing to be laid out
   again first. The commented template on /bodybuilding/ shows the shape.
   Columns are set in responsive.css.
   -------------------------------------------------------------------------- */

.checkin-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.checkin {
  display: grid;
  gap: var(--space-md);
  padding-block-start: var(--space-md);
  border-block-start: var(--border-width) solid var(--color-border);
}

.checkin__date {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-accent);
}

.checkin__views {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2xs);
}

.checkin__notes {
  margin-block-start: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Empty state - where real data will eventually live
   -------------------------------------------------------------------------- */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2xs);
  padding: var(--space-lg) var(--space-md);
  border: var(--border-width) dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: rgba(255, 255, 255, 0.012);
}

.empty-state__title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-muted);
}

.empty-state__body {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   404
   -------------------------------------------------------------------------- */

.error-page {
  display: flex;
  align-items: center;
  min-block-size: calc(100dvh - var(--header-height));
  padding-block: var(--space-2xl);
}

.error-page__code {
  font-family: var(--font-mono);
  font-size: clamp(3.5rem, 2rem + 7vw, 7rem);
  font-weight: var(--weight-bold);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  color: var(--color-accent);
}
