/* ==========================================================================
   HTS Coatings — Brand system v2 (matched to Facebook icon)
   Navy hex + silver gear + white H.
   Clear. Kind. Auditable. Fast.
   ========================================================================== */

/* ── Web fonts ────────────────────────────────────────────────────────
   Self-hosted woff2 (latin subset). Inter + Oswald + Fraunces all ship
   as variable fonts — one file covers the full weight range. Inter is
   preloaded in the document head so it lands ahead of the CSS fetch.
   font-display: swap shows fallback text while the woff2 downloads. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('/fonts/oswald-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/fraunces-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/fraunces-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Core brand (from icon) */
  --navy: #003b5c;           /* HTS brand navy — matches the logo (Ashley 2026-07-21) */
  --navy-dark: #002b43;      /* deeper marine — footer/CTA grounding, hover */
  --navy-light: #2f6e91;     /* lighter marine — hover accents for cards/links */
  --silver: #a5a5a5;         /* gear of icon */
  --silver-dark: #7a7a7a;    /* muted silver for secondary */
  --silver-light: #d0d0d0;   /* bright silver for dark-bg accents */

  /* Secondary accent — pulled from HTS LinkedIn card system (amber/orange
     blocks, data-viz bars, callout edges). Use sparingly as spice. */
  --orange: #f5a623;
  --orange-dark: #d4901b;
  --orange-light: #fbb94d;

  /* Neutrals */
  --ink: #111111;
  --charcoal: #1a1a1a;
  --charcoal-soft: #2a2a2a;
  --white: #ffffff;
  --canvas: #ffffff;         /* body bg — clean industrial white */
  --canvas-alt: #f4f5f7;     /* section alt — cool light gray */
  --line: #e4e6ea;           /* hairline borders */

  /* Text */
  --text: var(--charcoal);
  --text-muted: #555555;
  --text-soft: #7a7a7a;

  /* Semantic */
  --success: #10b981;
  --error: #dc2626;
  --warn: #d97706;

  /* Fonts */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Oswald', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-serif: 'Fraunces', Georgia, serif;

  /* Spacing */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2.5rem;
  --space-xl: 4rem;
  --space-xxl: 6rem;

  /* Layout */
  --max-width: 72rem;
  --content-width: 60rem;
  --radius: 4px;
  --radius-lg: 10px;

  /* Motion */
  --ease: cubic-bezier(.2, .8, .2, 1);
  --motion: 220ms;
}

* { box-sizing: border-box; }

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

/* Every id target clears the sticky header when deep-linked. Previously only
   applied inline on a handful of article cards; now global so nav-anchor jumps
   never hide under the header band. */
[id] { scroll-margin-top: 6rem; }

/* Visible focus ring fallback. Browsers give inputs one for free but nav
   links, CTA buttons, and anchor-styled links fall back to nothing without
   this. :focus-visible keeps mouse clicks quiet. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
summary:focus-visible,
[role="button"]:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: var(--radius);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--navy); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; transition: color var(--motion) var(--ease); }
a:hover { color: var(--navy-dark); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--ink);
  margin: 0 0 var(--space) 0;
}

h1 { font-size: clamp(2rem, 5vw + 1rem, 3.75rem); letter-spacing: -0.01em; }
h2 { font-size: clamp(1.5rem, 2.5vw + 1rem, 2.5rem); }
h3 { font-size: clamp(1.15rem, 1.5vw + 0.5rem, 1.5rem); }

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

.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;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.85rem 1.5rem;
  font-family: var(--font-display);
  font-size: 0.95rem; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease), color var(--motion) var(--ease), transform var(--motion) var(--ease);
  min-height: 48px;
}
.btn--primary { background: var(--navy); color: var(--white); border-color: var(--navy); }
.btn--primary:hover { background: var(--navy-dark); border-color: var(--navy-dark); color: var(--white); }
.btn--ghost { background: transparent; color: var(--ink); border-color: currentColor; }
.btn--ghost:hover { background: var(--ink); color: var(--white); }
.btn--on-dark { color: var(--white); border-color: var(--white); background: transparent; }
.btn--on-dark:hover { background: var(--white); color: var(--ink); }

/* ---------- Site header ---------- */
.site-header {
  background: var(--canvas);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 100;
  /* Header height is consumed by the fixed mobile drawer's `top:`
     offset (var(--header-h)). Keeping the variable here means a
     compound landscape media query can shrink it for short
     viewports without re-declaring the drawer rule. */
  --header-h: 64px;
}
.site-header__inner {
  max-width: var(--max-width);
  margin: 0 auto;
  /* Safe-area insets pad past the iPhone notch when in landscape
     (notch sits on the left-or-right edge), so the brand and
     hamburger never get clipped behind it. */
  padding: 0.65rem max(1.25rem, env(safe-area-inset-right)) 0.65rem max(1.25rem, env(safe-area-inset-left));
  min-height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
}
.site-brand {
  display: flex; align-items: center; gap: 0.7rem;
  text-decoration: none;
  color: var(--ink);
  font-family: var(--font-display);
}
.site-brand__icon {
  width: 44px; height: 44px; display: block;
  flex-shrink: 0;
}
.site-brand__wordmark {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
  gap: 0.15rem;
}
.site-brand__name {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}
.site-brand__subtitle {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Navigation */
.site-nav { flex: 1; }
.site-nav__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; justify-content: flex-end;
  gap: 1.75rem;
}
.site-nav__link {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-decoration: none;
  padding: 0.25rem 0;
  border-bottom: 2px solid transparent;
}
.site-nav__link:hover { color: var(--navy); border-bottom-color: var(--orange); }
.site-nav__link.is-current { color: var(--navy); border-bottom-color: var(--navy); }

.site-nav__cta {
  background: var(--navy);
  color: var(--white) !important;
  padding: 0.55rem 1rem;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none !important;
  border-bottom: none !important;
  min-height: 44px;
  display: inline-flex; align-items: center;
  transition: background var(--motion) var(--ease);
}
.site-nav__cta:hover { background: var(--navy-dark); color: var(--white) !important; }

/* Nav toggle (mobile) */
.nav-toggle {
  display: none;
  background: none; border: 0; padding: 0.5rem;
  cursor: pointer;
  width: 44px; height: 44px;
  flex-direction: column; justify-content: center; gap: 5px;
  border-radius: var(--radius);
}
.nav-toggle:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}
.nav-toggle__line {
  display: block; width: 24px; height: 2px;
  background: var(--ink);
  margin: 0 auto;
  transform-origin: center;
  transition: transform var(--motion) var(--ease), opacity var(--motion) var(--ease);
}
/* Animate the three lines into an X when the menu is open. The middle
   line fades, the outer lines pivot to ±45° and translate to overlap. */
.nav-toggle[aria-expanded="true"] .nav-toggle__line:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__line:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__line:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ---------- Hero ---------- */
.hero {
  background: var(--navy-dark);
  color: var(--white);
  padding: clamp(4rem, 8vw, 7rem) 1.25rem;
  position: relative;
  overflow: hidden;
}
.hero::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 85% 15%, rgba(208, 208, 208, 0.14), transparent 55%),
              radial-gradient(ellipse at 15% 85%, rgba(10, 22, 40, 0.55), transparent 65%);
  pointer-events: none;
}
.hero::after {
  /* Subtle brand watermark floating behind hero content */
  content: ''; position: absolute;
  right: -120px; bottom: -120px;
  width: 520px; height: 520px;
  background: url('/images/hts-mark-white.png') no-repeat center / contain;
  opacity: 0.06;
  pointer-events: none;
}
.hero__inner {
  max-width: var(--content-width);
  margin: 0 auto;
  position: relative;
}
.hero__eyebrow {
  font-family: var(--font-display);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--silver-light);
  margin: 0 0 0.75rem;
}
.hero__title {
  color: var(--white);
  font-size: clamp(2rem, 5vw + 1rem, 4rem);
  margin: 0 0 1.25rem;
  font-weight: 600;
}
/* The headline accent — reachable by owners via the editor's I (italic)
   button, since the hero title renders inline markdown (*words* → <em>). */
.hero__title em {
  color: var(--silver-light);
  font-style: italic;
  font-family: var(--font-serif);
  font-weight: 400;
}
.hero__lede {
  font-size: clamp(1rem, 1vw + 0.5rem, 1.2rem);
  color: rgba(255, 255, 255, 0.85);
  max-width: 48rem;
  margin: 0 0 2rem;
}
.hero__ctas { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.hero__ctas .btn--ghost { color: var(--white); border-color: rgba(255, 255, 255, 0.5); }
.hero__ctas .btn--ghost:hover { background: var(--white); color: var(--ink); border-color: var(--white); }
.hero__ctas .btn--primary { background: var(--white); color: var(--navy); border-color: var(--white); }
.hero__ctas .btn--primary:hover { background: var(--silver-light); color: var(--navy-dark); border-color: var(--silver-light); }

/* ---------- Sections ---------- */
.section {
  padding:
    clamp(3rem, 6vw, 5rem)
    max(1.25rem, env(safe-area-inset-right))
    clamp(3rem, 6vw, 5rem)
    max(1.25rem, env(safe-area-inset-left));
}
.section--alt { background: var(--canvas-alt); }
.section--dark { background: var(--ink); color: var(--white); }
.section--dark h2, .section--dark h3 { color: var(--white); }
.section__inner { max-width: var(--max-width); margin: 0 auto; }
.section__header { max-width: 48rem; margin: 0 0 2.5rem; }
.section__header h2 { margin-bottom: 0.5rem; }
.section__header p { font-size: 1.1rem; color: var(--text-muted); margin: 0; }

/* ---------- Cards ---------- */
.cards {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
.card {
  background: var(--white);
  padding: 1.75rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: flex; flex-direction: column;
  transition: transform var(--motion) var(--ease), box-shadow var(--motion) var(--ease), border-color var(--motion) var(--ease);
}
/* Only cards that actually link anywhere get the hover lift — a
   decorative container signaling clickability it doesn't honor is a
   worse UX than no hover at all. :has(a) covers "Details" links on
   services / solutions / notes cards, "Event site" links on the home
   events card, and the admin "Edit X" links when signed in. Pure
   content cards (if any) stay flat. */
.card:has(a):hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(35, 64, 102, 0.08);
  border-color: var(--navy-light);
}
.card__title { margin: 0 0 0.5rem; }
.card__short { color: var(--text-muted); margin: 0 0 1rem; }
.card__list {
  list-style: none;
  padding: 0; margin: 0 0 1.25rem;
  display: flex; flex-wrap: wrap; gap: 0.35rem;
  font-size: 0.85rem;
}
.card__list li {
  padding: 0.2rem 0.6rem;
  background: var(--canvas-alt);
  border-radius: var(--radius);
  font-family: var(--font-display);
  letter-spacing: 0.03em;
  color: var(--text);
}
.card__link {
  margin-top: auto;
  font-family: var(--font-display);
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
  color: var(--navy);
  padding: 0.85rem 0 0.25rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  border-top: 1px solid var(--line);
}
.card__link::after { content: ' →'; transition: margin-left var(--motion) var(--ease); }
.card__link:hover::after { margin-left: 0.2rem; }

/* ---------- Proof row ---------- */
.proof__list {
  list-style: none; padding: 0; margin: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);   /* 8 credential tiles → even 4 + 4 */
  gap: 1.25rem;
}
@media (max-width: 860px) { .proof__list { grid-template-columns: repeat(2, 1fr); } }
.proof__item {
  background: var(--white);
  padding: 1.25rem;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 0.25rem;
  text-align: center;      /* labels share the tiles' center axis */
}
.proof__item strong {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--ink);
}
.proof__item span { font-size: 0.85rem; color: var(--text-muted); }
/* Responsive video embeds — a YouTube/Vimeo link on its own line renders
   as a 16:9 player (see lib/content.js embedVideoUrls). */
.video-embed-container {
  position: relative;
  width: 100%;
  padding-bottom: 56.25%;   /* 16:9 */
  height: 0;
  margin: 1.75rem 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
}
.video-embed-container iframe {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  border: 0;
}
/* YouTube Shorts are 9:16 — a portrait frame, capped and centered, instead
   of pillarboxing them into the 16:9 default. */
.video-embed-container--portrait {
  max-width: 24rem;
  margin-left: auto;
  margin-right: auto;
  padding-bottom: min(177.78%, 42.7rem);   /* 16:9 inverted, capped with the width */
}
/* Dedicated video spot (content_type=video_url): the empty state is an
   editor-only invitation — visitors never see the section until a video
   is set (the view gates on the value). */
.video-slot__empty {
  display: block;
  padding: 2.5rem 1.5rem;
  border: 2px dashed var(--line);
  border-radius: var(--radius-lg);
  color: var(--text-muted);
  font-size: 0.95rem;
  cursor: pointer;
}
.video-slot__empty:hover { border-color: var(--navy-light); color: var(--navy); }

/* Edit mode, filled video slot: iframes swallow clicks, so without this the
   owner could never click the player to swap it. A transparent catcher over
   the slot routes every click to the inline editor, with a visible pill so
   the affordance isn't a secret. (Playback while logged in: log out or use
   a private window — the pill says so on hover via title in the markup.) */
body.edit-mode .video-slot { position: relative; }
body.edit-mode .video-slot::after {
  content: '\270E  Click to change video';
  position: absolute; inset: 0;
  display: flex; align-items: flex-start; justify-content: flex-end;
  padding: 0.6rem;
  font: 600 0.72rem var(--font-display);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--white);
  cursor: pointer;
}
body.edit-mode .video-slot::before {
  content: '';
  position: absolute; top: 0.35rem; right: 0.35rem;
  width: 13.5rem; height: 1.9rem;
  background: rgba(0, 43, 67, 0.85);
  border-radius: 999px;
}

/* Multi-line plain-text spots keep their line breaks: a textarea that
   preserves Returns while the page flattens them is a lie. pre-line shows
   the owner's newlines without granting any styling capability. md fields
   excluded — their multi-line template markup would render stray breaks. */
[data-editable][data-content-type="paragraph"]:not([data-md]) { white-space: pre-line; }

/* Optional inline field, empty state: a faint italic prompt shows in edit mode
   so the owner can click to add it back. Visitors never see it — the view
   skips rendering the element entirely when it's blank + logged out. */
body.edit-mode [data-editable][data-optional]:empty::before {
  content: attr(data-placeholder);
  opacity: 0.55;
  font-style: italic;
  font-weight: 400;
}

/* ── Anchor-arrival highlight ──────────────────────────────────────────────
   Arriving via an item anchor (the admin "View live" links, or any /page#slug
   URL): the landed card/bio quietly picks itself out of the grid, so the
   link's promise — "show me THIS one" — is kept visually. Static ring only;
   no motion to gate. Sections (#problems, #industries) aren't matched — the
   ring is for items, not whole page regions. */
.card:target,
article[id]:target {
  outline: 2px solid var(--navy-light);
  outline-offset: 4px;
  border-radius: var(--radius-lg);
}
/* Instagram embeds are portrait — cap the width and center. */
.instagram-embed-container {
  position: relative;
  max-width: 400px;
  margin: 1.75rem auto;
  aspect-ratio: 400 / 510;
  border-radius: var(--radius);
  overflow: hidden;
}
.instagram-embed-container iframe {
  width: 100%; height: 100%; border: 0;
}

/* Markdown spec tables (process + coating detail pages). Browser default
   center-aligns <th> while cells sit left — so headers get an explicit
   left-align, the label column a stable width, and rows a hairline rule. */
.prose table,
.admin-help table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.75rem 0;
  font-size: 0.95rem;
}
.prose thead th,
.admin-help thead th {
  text-align: left;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  border-bottom: 2px solid var(--line);
  padding: 0.6rem 1rem 0.6rem 0;
}
.prose tbody td,
.admin-help tbody td {
  text-align: left;
  padding: 0.55rem 1rem 0.55rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.prose tbody tr:last-child td,
.admin-help tbody tr:last-child td { border-bottom: none; }
.prose tbody td:first-child,
.prose thead th:first-child,
.admin-help tbody td:first-child,
.admin-help thead th:first-child {
  width: 38%;
  padding-right: 1.5rem;
  color: var(--text);
}
@media (max-width: 560px) {
  .prose table { font-size: 0.9rem; }
  .prose tbody td:first-child, .prose thead th:first-child { width: 44%; }
}
/* Phones: the guide's two-column prose tables STACK — each row becomes a
   block with the "where" as a bold lead-in and the "what happens" beneath
   it, full width. Side-by-side columns at 390px break words mid-syllable. */
@media (max-width: 480px) {
  .admin-help table,
  .admin-help tbody,
  .admin-help tr,
  .admin-help td { display: block; width: 100%; }
  .admin-help thead { display: none; }   /* headers are implicit once stacked */
  .admin-help tbody tr {
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--line);
  }
  .admin-help tbody tr:last-child { border-bottom: none; }
  .admin-help tbody td { padding: 0; border-bottom: none; }
  .admin-help tbody td:first-child {
    padding-right: 0;
    margin-bottom: 0.25rem;
    font-weight: 600;
    color: var(--ink);
  }
}

/* Spatial reorder controls (admin lists) — the ↑/↓ that replace raw
   sort-order number fields. */
.admin-move { grid-area: move; align-self: center; display: inline-flex; flex-direction: column; gap: 4px; }
.admin-move__form { margin: 0; line-height: 0; }
.admin-move__btn {
  width: 2rem; min-height: 1.9rem;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 1px solid var(--line); border-radius: 4px;
  background: var(--white); color: var(--navy); cursor: pointer;
  font-size: 0.85rem; line-height: 1;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease);
}
.admin-move__btn:hover:not(:disabled) { background: var(--canvas-alt); border-color: var(--navy-light); }
.admin-move__btn:disabled { opacity: 0.3; cursor: default; }

/* Breadcrumb trail — sits in the hero eyebrow slot; inherits color so it
   stays legible on both plain and image heroes. Ancestors link, current is
   bold + unlinked. Conveys where-you-are and where-you-can-go. */
.breadcrumb { margin: 0 0 0.85rem; }
.breadcrumb__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem;
  font-size: 0.8rem; letter-spacing: 0.02em;
}
.breadcrumb__item { display: flex; align-items: center; gap: 0.45rem; }
.breadcrumb__item + .breadcrumb__item::before { content: "/"; opacity: 0.4; }
.breadcrumb__item a { color: inherit; opacity: 0.72; text-decoration: none; }
.breadcrumb__item a:hover { opacity: 1; text-decoration: underline; }
.breadcrumb__item [aria-current] { font-weight: 600; opacity: 1; }

/* Capability cards — every process/method/material in a service is a uniform
   card with a morsel. Cards that have a dedicated detail page link and carry
   an arrow glyph (↗); the rest are static and otherwise identical. Selector
   prefixed so text-decoration:none beats the global `.prose a` underline. */
.process-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
  margin: 1.25rem 0 0;
}
.prose .process-cards .process-card,
.process-cards .process-card {
  position: relative;
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 1.4rem 1.35rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  color: var(--text);
  text-decoration: none;
}
/* Only linked cards are interactive (lift + border + arrow nudge). */
.process-cards a.process-card {
  transition: transform var(--motion) var(--ease), box-shadow var(--motion) var(--ease), border-color var(--motion) var(--ease);
}
.process-cards a.process-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(26, 48, 80, 0.10);
  border-color: var(--navy-light);
}
.process-card__name { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--ink); }
.process-card--link .process-card__name { padding-right: 1.5rem; }
.process-card__abbr { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-soft); }
.process-card__desc { font-size: 0.85rem; line-height: 1.45; color: var(--text-muted); margin-top: 0.4rem; }
/* Arrow glyph — the "there's a page behind this one" tell. Persistent on
   linked cards, nudges out on hover. */
.process-card__go {
  position: absolute; top: 1.15rem; right: 1.2rem;
  color: var(--navy); font-size: 1.05rem; line-height: 1;
  transition: transform var(--motion) var(--ease);
}
.process-cards a.process-card:hover .process-card__go { transform: translate(2px, -2px); }

/* ── Image capability cards ────────────────────────────────────────────────
   Each process shows its own picture (the "lights up on hover" treatment the
   client loved on the old site). These render INSIDE .prose on the service
   page, so the modifiers are scoped to match that (0,3,0) specificity — else
   `.prose .process-cards .process-card { background: white }` wins and the
   photo TILES instead of covering. Photo + top scrim are set inline per card. */
.prose .process-cards .process-card--image,
.process-cards .process-card--image,
.prose .process-cards .process-card--brand,
.process-cards .process-card--brand {
  min-height: 12rem;
  justify-content: flex-start;      /* labels top-aligned, uniform across the grid */
  background-size: cover;
  background-repeat: no-repeat;     /* kills the landscape-photo tiling */
  background-position: center;
  border: none;
  color: var(--white);
  overflow: hidden;
}
/* Brand fallback for a process with no photo: rich navy so it marries with the
   photo cards rather than reading as an empty box. */
.prose .process-cards .process-card--brand,
.process-cards .process-card--brand {
  background-color: var(--navy);
  background-image: linear-gradient(150deg, var(--navy) 0%, var(--navy-dark) 58%, #14233b 100%);
}
/* White-on-dark text for both image + brand cards. The text-shadow is the key
   to legibility over UNPREDICTABLE photos: invisible over the dark action shots
   (it blends into the dark), but it throws a dark halo that lifts the label off
   a light image (e.g. the Spray & Fuse placeholder) so it always pops. */
.process-card--image .process-card__name,
.process-card--brand .process-card__name {
  color: var(--white);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7), 0 2px 14px rgba(0, 0, 0, 0.45);
}
.process-card--image .process-card__abbr,
.process-card--brand .process-card__abbr {
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.65), 0 1px 10px rgba(0, 0, 0, 0.4);
}
.process-card--image .process-card__desc,
.process-card--brand .process-card__desc {
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.process-card--image .process-card__go,
.process-card--brand .process-card__go {
  color: var(--white);
  text-shadow: 0 1px 5px rgba(0, 0, 0, 0.6);
}
/* Hover "lights up" — brighten the image + a firmer lift, echoing the old site. */
.process-cards a.process-card--image,
.process-cards a.process-card--brand {
  transition: transform var(--motion) var(--ease), box-shadow var(--motion) var(--ease), filter var(--motion) var(--ease);
}
.process-cards a.process-card--image:hover,
.process-cards a.process-card--brand:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 30px rgba(26, 48, 80, 0.28);
}
.process-cards a.process-card--image:hover { filter: brightness(1.09); }
.process-cards a.process-card--brand:hover { filter: brightness(1.12); }

/* Official trademarked lockup in the header (attorney-required artwork). */
.site-brand__lockup {
  display: block;
  height: 2.4rem;
  width: auto;
}
@media (max-width: 480px) {
  .site-brand__lockup { height: 2rem; }
}

/* ISO tile doubles as a link to the certificate PDF. */
.proof__item-cert {
  margin-top: 0.55rem;    /* top-align with the other badges (was bottom-pinned) */
  display: block;
  width: 100%;
}
.proof__item-cert .proof__item-logo { margin-top: 0; }
.proof__item-cert:hover .proof__item-logo { border-color: var(--steel, #2b4a6f); }
/* Always-visible "this one's a link" cue — the other credential tiles are
   static logos, so the certificate needs a signal that survives touch (no hover). */
.proof__item-cert-cue {
  display: inline-block;
  margin-top: 0.55rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.proof__item-cert:hover .proof__item-cert-cue,
.proof__item-cert:focus-visible .proof__item-cert-cue { color: var(--navy-light); }

/* Credential marks sit in uniform "tiles" — same width/height across the
   row, logo centered inside — so mixed aspect ratios read as one system. */
.proof__item-logo,
.proof__item-tile {
  margin-top: 0.55rem;     /* top-align under the label so the row lines up */
  width: 100%;
  height: 4.5rem;
  padding: 0.65rem 0.9rem;
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.proof__item-logo {
  display: block;
  object-fit: contain;     /* centers the mark inside the tile */
}
/* Typographic tile — used where no licensed mark is on hand (Inc. 5000). */
.proof__item-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.proof__item-tile strong {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
}
.proof__item-tile small {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 0.3rem;
}

/* ---------- Problems ---------- */
.problems__list {
  list-style: none; padding: 0; margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem;
}
.problems__list li {
  padding: 1.25rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  display: flex; flex-direction: column; gap: 0.25rem;
  position: relative;
}
.problems__list strong { font-family: var(--font-display); font-size: 1.1rem; color: var(--navy); }
.problems__list span { font-size: 0.9rem; color: var(--text-muted); }

/* ---------- CTA band ---------- */
.cta-band {
  background: var(--navy);   /* unified with the footer — one brand-blue dark base */
  color: var(--white);
  padding: clamp(3rem, 5vw, 4.5rem) 1.25rem;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.cta-band::before {
  content: ''; position: absolute;
  left: -80px; top: -80px;
  width: 320px; height: 320px;
  background: url('/images/hts-mark-silver.png') no-repeat center / contain;
  opacity: 0.05;
  pointer-events: none;
}
.cta-band .section__inner { position: relative; z-index: 1; }
.cta-band h2 { color: var(--white); }
.cta-band p { color: rgba(255, 255, 255, 0.85); margin: 0 0 1.5rem; font-size: 1.1rem; }
.cta-band .btn--primary { background: var(--white); color: var(--navy); border-color: var(--white); }
.cta-band .btn--primary:hover { background: var(--silver-light); color: var(--navy-dark); border-color: var(--silver-light); }

/* ---------- Mission block (About page) ---------- */
.mission-block {
  padding: 2.5rem 2rem;
  background: var(--canvas-alt);
  border-radius: var(--radius);
  margin-top: 3rem;
  position: relative;
  overflow: hidden;
}
.mission-block::after {
  content: ''; position: absolute;
  right: -40px; bottom: -40px;
  width: 200px; height: 200px;
  background: url('/images/hts-mark-navy.png') no-repeat center / contain;
  opacity: 0.07;
  pointer-events: none;
}
.mission-block > * { position: relative; z-index: 1; }
.mission-block h3 { margin-top: 0; color: var(--navy); }
.mission-block .mission-quote {
  font-family: var(--font-serif);
  font-size: 1.25rem;
  line-height: 1.5;
  font-style: italic;
  margin: 0;
  color: var(--text);
}

/* ---------- Footer ---------- */
.site-footer {
  /* Brand-blue, grounded a shade deeper than the CTA band above it + a
     hairline seam, so the two read as distinct sections instead of one
     wash of blue. */
  background: var(--navy-dark);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.85);
  /* Safe-area insets cover the home-indicator zone on iPhone (bottom)
     and the notch in landscape (left/right). Without them the legal
     line + cert badges can sit under the gesture bar. */
  padding:
    3.5rem
    max(1.25rem, env(safe-area-inset-right))
    max(2rem, env(safe-area-inset-bottom))
    max(1.25rem, env(safe-area-inset-left));
}
.site-footer a {
  color: rgba(255, 255, 255, 0.85);
  display: inline-block;
  /* Generous tap target — work-glove-friendly per the brief. */
  min-height: 28px;
  padding: 0.15rem 0;
}
.site-footer a:hover { color: var(--silver-light); }
.site-footer a:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
  border-radius: 2px;
}
.site-footer__inner {
  max-width: var(--max-width);
  margin: 0 auto;
  display: grid;
  gap: 2rem;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
}
.site-footer__col h3 {
  color: var(--white);
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 0.75rem;
}
.site-footer__col ul { list-style: none; padding: 0; margin: 0; }
.site-footer__col li { padding: 0.25rem 0; }
.site-footer__brand {
  font-family: var(--font-display);
  font-size: 1.5rem; font-weight: 600;
  color: var(--white);
  margin-bottom: 0.5rem;
}
.site-footer__tagline {
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.95rem;
  margin-bottom: 1rem;
}
.site-footer__mission {
  font-family: var(--font-serif);
  font-size: 0.95rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
}
.site-footer__address {
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.9rem;
}

.site-footer__certs {
  max-width: var(--max-width);
  margin: 2rem auto 0;
  padding-top: 2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: flex; gap: 1rem; flex-wrap: wrap;
  justify-content: center;
}
.site-footer__cert {
  padding: 0.35rem 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.75);
}
.site-footer__legal {
  max-width: var(--max-width);
  margin: 1.5rem auto 0;
  text-align: center;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.5);
}

/* ---------- Error page ---------- */
.error-page { padding: clamp(4rem, 10vw, 8rem) 1.25rem; text-align: center; }
.error-page__code {
  font-family: var(--font-display);
  font-size: clamp(4rem, 10vw, 7rem);
  font-weight: 700;
  color: var(--navy);
  margin: 0 0 1rem;
  line-height: 1;
}
.error-page__title { margin-bottom: 1rem; }
.error-page__message { max-width: 36rem; margin: 0 auto 2rem; color: var(--text-muted); }
.error-page__ctas { display: flex; gap: 0.75rem; flex-wrap: wrap; justify-content: center; }

/* ---------- Generic page shell (services/about/contact/events placeholders) ---------- */
.page-hero {
  background: var(--canvas-alt);
  padding: clamp(3rem, 6vw, 5rem) 1.25rem 2rem;
  position: relative;
  overflow: hidden;
}
.page-hero::before {
  content: ''; position: absolute;
  right: -60px; top: -60px;
  width: 280px; height: 280px;
  background: url('/images/hts-mark-navy.png') no-repeat center / contain;
  opacity: 0.06;
  pointer-events: none;
}
/* Materials page: a brushed-steel wash gives the catalog hero some life
   when no photo is set — a cool steel base with a soft top-left sheen so it
   reads as intentional, not a flat panel. Dark hero text stays legible.
   An uploaded hero (page-hero--with-image) takes over when present. */
.page-hero--materials {
  background:
    linear-gradient(155deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 45%),
    linear-gradient(120deg, #d6e0ec 0%, #bccddf 48%, #d3dded 78%, #e6ecf4 100%);
}
/* Trademark / applicator disclaimer — a quiet footnote closing the catalog,
   set off by a hairline so it reads as fine print, not a stark block. */
.coatings-legal {
  max-width: 52rem;
  margin: 2.5rem auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-soft);
  text-align: center;
}
.page-hero__inner { max-width: var(--content-width); margin: 0 auto; position: relative; z-index: 1; }
.page-hero__eyebrow { font-family: var(--font-display); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.15em; color: var(--navy); margin: 0 0 0.5rem; }
.page-hero__title { margin: 0 0 1rem; }
.page-hero__lede { font-size: 1.15rem; color: var(--text-muted); max-width: 48rem; margin: 0; }

/* When a hero image is applied, the base h1 / muted-gray colors don't
   survive over the photo — explicit white + soft shadow gives the
   headline the contrast it needs without looking drop-shadow heavy. */
.page-hero--with-image { padding: clamp(5rem, 10vw, 8rem) 1.25rem clamp(4rem, 8vw, 6rem); }
.page-hero--with-image::before { display: none; } /* kill the navy watermark on image heroes */
.page-hero--with-image .page-hero__eyebrow {
  color: var(--silver-light);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
.page-hero--with-image .page-hero__title {
  color: var(--white);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
}
.page-hero--with-image .page-hero__lede {
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
}
/* Buttons on top of a photo need white-on-dark treatment or they
   vanish into the gradient. Mirrors the .hero__ctas override that
   already applies on the home hero. */
.page-hero--with-image .btn--ghost {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.6);
}
.page-hero--with-image .btn--ghost:hover {
  background: var(--white);
  color: var(--ink);
  border-color: var(--white);
}
.page-hero--with-image .btn--primary {
  background: var(--white);
  color: var(--navy);
  border-color: var(--white);
}
.page-hero--with-image .btn--primary:hover {
  background: var(--silver-light);
  color: var(--navy-dark);
  border-color: var(--silver-light);
}

/* ---------- Contact layout ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
}
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.contact-form label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-weight: 500;
  color: var(--text);
}
.contact-form input,
.contact-form select,
.contact-form textarea {
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  min-height: 48px;
  background-color: var(--white);
  transition: border-color var(--motion) var(--ease);
}
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15);
}
.contact-form textarea {
  min-height: 100px;
  resize: vertical;
}
/* File input gets lighter treatment — default browser UI for the button,
   dashed box around the whole label so it reads as "droppable" without
   competing with the primary-styled Send button below. min-width:0 on
   the label + input is the fix for iOS Safari blowing the container
   wider than the viewport once a filename displays inside the native
   input; flex items default to min-width:auto which won't shrink below
   intrinsic content width. */
.contact-form__photo {
  padding: 0.85rem 1rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: var(--canvas-alt);
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}
.contact-form__photo input[type="file"] {
  padding: 0.4rem 0;
  border: 0;
  min-height: 0;
  background: transparent;
  font-size: 0.95rem;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.contact-form__photo input[type="file"]:focus {
  box-shadow: none;
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: var(--radius);
}
.contact-form__photo-hint {
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
.contact-form .quote-fields,
.contact-form [data-show-for] {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.contact-form [data-show-for][hidden] { display: none; }

/* Admin inbox — attached customer photos. Constrained thumb (max 320px
   tall) with an "Open full size" affordance. Full file opens in a new
   tab so admins can zoom / download. */
.admin-contact-photo {
  display: inline-flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0 0 0.85rem;
  padding: 0.4rem;
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--navy);
  max-width: 420px;
}
.admin-contact-photo img {
  max-width: 100%;
  max-height: 320px;
  width: auto;
  height: auto;
  border-radius: calc(var(--radius) - 2px);
  display: block;
}
.admin-contact-photo span {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--navy);
}
.admin-contact-photo:hover,
.admin-contact-photo:focus-visible {
  border-color: var(--navy);
}

/* ---------- Mobile + landscape-iPhone navigation ----------
   Three-agent audit + design synthesis (Apr 2026): replaces the older
   absolute-positioned drawer that overflowed the landscape-iPhone
   viewport with a fixed-position sheet anchored beneath the sticky
   header. The drawer fills the viewport's remaining height
   (top: var(--header-h); bottom: 0) and scrolls internally if the
   item count ever outgrows the available room — no more trapped
   scroll-locked state on iPhone SE landscape (375px tall).

   Breakpoint bumped 768 → 900 so iPhone 13/14/15 in landscape
   (844-932px wide) get the drawer rather than wrapping the desktop
   horizontal nav onto two lines. Compound `(max-height: 540px) and
   (orientation: landscape)` block below switches to a 2-column grid
   so all 7 items + CTA fit without internal scroll on short
   viewports. Safe-area insets cover notch placement on every side.

   Drawer is on-brand navy with cream type and an orange CTA — a
   typographic menu, not an iconographic one. */
@media (max-width: 899.98px) {
  .nav-toggle { display: flex; }

  .site-nav {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--navy);
    color: var(--canvas);
    /* Safe-area insets land left/right (landscape notch + home
       indicator side) and bottom (home-indicator swipe zone). */
    padding:
      1.25rem
      max(1.25rem, env(safe-area-inset-right))
      max(1.5rem, env(safe-area-inset-bottom))
      max(1.25rem, env(safe-area-inset-left));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.18);
    flex: initial;
    z-index: 90;
    /* Closed state: invisible, untappable, slightly raised. JS toggles
       .is-open to flip to the open state below. Compositor-only
       transition (transform + opacity) hits 60fps. */
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
    transition:
      opacity var(--motion) var(--ease),
      transform var(--motion) var(--ease);
  }
  .site-nav.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
  /* iOS rubber-band defeat: position:fixed body lock keeps scroll
     position pinned while drawer is open. JS preserves and restores
     scrollY to prevent the page jumping to the top on close. */
  body.nav-open {
    overflow: hidden;
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
  }

  .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
  }

  .site-nav__link {
    display: block;
    padding: 0.95rem 0.85rem;
    margin: 0;
    color: var(--canvas);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 0;
    font-size: 1.15rem;
    /* Left-edge accent reserved for the active item (filled below).
       Setting transparent here keeps width consistent so non-active
       items don't shift when an item becomes current. */
    box-shadow: inset 3px 0 0 0 transparent;
    transition: background var(--motion) var(--ease), color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
  }
  .site-nav__link:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--orange);
    border-bottom-color: rgba(255, 255, 255, 0.08);
  }
  .site-nav__link:focus-visible {
    background: rgba(255, 255, 255, 0.08);
    color: var(--orange);
    border-bottom-color: rgba(255, 255, 255, 0.08);
    outline: 2px solid var(--orange);
    outline-offset: -2px;
  }
  .site-nav__link.is-current {
    color: var(--orange);
    font-weight: 600;
    background: rgba(255, 255, 255, 0.04);
    /* Override the desktop default's border-bottom-color: navy
       (which inherits at higher specificity from the outer scope's
       .site-nav__link.is-current rule) so the active item doesn't
       grow an invisible navy underline on the navy drawer. */
    border-bottom-color: rgba(255, 255, 255, 0.08);
    /* Vercel-style left-edge accent reads cleanly on dark drawer. */
    box-shadow: inset 3px 0 0 0 var(--orange);
  }

  .site-nav__cta {
    margin-top: 0.85rem;
    background: var(--orange);
    color: var(--ink) !important;
    text-align: center;
    justify-content: center;
    padding: 0.85rem 1.25rem;
    min-height: 52px;
    font-size: 1.05rem;
    border-radius: var(--radius);
  }
  .site-nav__cta:hover {
    background: var(--orange-dark);
    color: var(--ink) !important;
  }
  .site-nav__cta:focus-visible {
    background: var(--orange-dark);
    color: var(--ink) !important;
    outline: 2px solid var(--canvas);
    outline-offset: 3px;
  }

  .site-footer__inner { grid-template-columns: 1fr; }
  .site-footer__col--brand { order: -1; }

  /* Hero CTAs stay side-by-side at tablet + landscape-phone widths;
     the phone-only stack lives at the END of the sheet (source order). */

  .contact-grid { grid-template-columns: 1fr; gap: 2rem; }
}

/* Compound landscape-phone regime: short viewport AND mobile width.
   Switches to a 2-column grid + tighter header so the drawer's 7
   items + CTA fit on iPhone SE landscape (667×375) and iPhone 15 Pro
   Max landscape (932×432) without internal scroll. Subtitle on the
   brand mark gets hidden — height we can't afford. */
@media (max-width: 899.98px) and (max-height: 540px) and (orientation: landscape) {
  .site-header { --header-h: 52px; }
  .site-header__inner { padding-top: 0.35rem; padding-bottom: 0.35rem; }
  .site-brand__icon { width: 36px; height: 36px; }
  .site-brand__subtitle { display: none; }

  .site-nav {
    padding-top: 0.85rem;
    padding-bottom: max(0.85rem, env(safe-area-inset-bottom));
  }
  .site-nav__list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 0.85rem;
    row-gap: 0;
  }
  /* The CTA li (last child) spans both columns so it reads as a
     full-width primary action below the link grid. */
  .site-nav__list > li:last-child { grid-column: 1 / -1; }

  .site-nav__link {
    padding: 0.65rem 0.6rem;
    font-size: 1rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  }
  .site-nav__cta {
    margin-top: 0.5rem;
    padding: 0.7rem 1rem;
    min-height: 48px;
    font-size: 0.95rem;
  }
}

/* ---------- Image slot — reusable hero/feature placeholder ----------
   Design intent: every page has generous territory for Storywright-produced
   imagery. Until those assets land, the slot renders a gradient field with
   a centered brand silhouette + small caption ("Storywright photo" etc.)
   When real imagery arrives, set inline style="background-image: url(...)"
   plus the .image-slot--filled class to swap out the gradient cleanly. */
.image-slot {
  position: relative;
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-dark) 100%);
  border-radius: var(--radius);
  overflow: hidden;
  background-size: cover;
  background-position: center;
}
.image-slot--16-9 { aspect-ratio: 16 / 9; }
.image-slot--4-3 { aspect-ratio: 4 / 3; }
.image-slot--1-1 { aspect-ratio: 1 / 1; }
.image-slot--3-4 { aspect-ratio: 3 / 4; }
.image-slot--21-9 { aspect-ratio: 21 / 9; }
.image-slot:not(.image-slot--filled)::before {
  content: '';
  position: absolute; inset: 0;
  background: url('/images/hts-mark-silver.png') no-repeat center / 32%;
  opacity: 0.45;
  pointer-events: none;
}
.image-slot__caption {
  position: absolute;
  bottom: 0.75rem; right: 0.75rem;
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.7rem;
  font-family: var(--font-display);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  padding: 0.3rem 0.7rem;
  background: rgba(0, 0, 0, 0.4);
  border-radius: var(--radius);
  pointer-events: none;
}
.image-slot--filled .image-slot__caption {
  display: none;
}
.image-slot--filled::after {
  /* Dark overlay for text legibility on real imagery */
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 55%);
  pointer-events: none;
}

/* ---------- Featured-capability callout band ----------
   Used for specialty offerings (BTHC-0005, signature process). Image on
   right, copy + accent CTA on left. Mobile stacks. Orange badge + accent
   button tie to the HTS LinkedIn visual system without going overboard. */
.callout-band {
  background: var(--canvas-alt);
  padding: clamp(3rem, 6vw, 5rem) 1.25rem;
}
.callout {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 3rem;
  align-items: center;
  max-width: var(--max-width);
  margin: 0 auto;
}
.callout__content .badge { margin-bottom: 0.75rem; }
.callout__content h2 { margin: 0.25rem 0 1rem; }
.callout__content p { font-size: 1.1rem; color: var(--text-muted); margin: 0 0 1.5rem; }
.callout__media { max-width: 24rem; width: 100%; }
@media (max-width: 768px) {
  .callout { grid-template-columns: 1fr; gap: 1.5rem; }
  .callout__media { max-width: 100%; }
}

/* ---------- Imagery band — 3-up grid of image slots ---------- */
.imagery-band {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}
@media (max-width: 900px) {
  .imagery-band { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .imagery-band { grid-template-columns: 1fr; }
}

/* ---------- Card variant with image on top ---------- */
.card--with-image {
  padding: 0;
  overflow: hidden;
}
.card--with-image .card__image {
  aspect-ratio: 4 / 3;
  position: relative;
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-dark) 100%);
  overflow: hidden;
  background-size: cover;
  background-position: center;
}
.card--with-image:not(.card--with-image--filled) .card__image::before {
  content: '';
  position: absolute; inset: 0;
  background: url('/images/hts-mark-silver.png') no-repeat center / 40%;
  opacity: 0.35;
  pointer-events: none;
}
.card--with-image .card__image__caption {
  position: absolute;
  bottom: 0.65rem; right: 0.65rem;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.65rem;
  font-family: var(--font-display);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  background: rgba(0, 0, 0, 0.4);
  border-radius: var(--radius);
}
.card--with-image .card__body {
  padding: 1.5rem 1.5rem 1.75rem;
  display: flex; flex-direction: column;
  flex: 1;
}
.card--with-image .card__title { margin-top: 0; }

/* ---------- Small orange accents ---------- */
.badge {
  display: inline-block;
  background: var(--orange);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius);
}
.btn--accent {
  background: var(--orange);
  color: var(--ink);
  border-color: var(--orange);
}
.btn--accent:hover {
  background: var(--orange-dark);
  border-color: var(--orange-dark);
  color: var(--ink);
}

/* ---------- Portrait image slot (for About / leadership) ---------- */
.portrait-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 1.25rem;
  margin: 2rem 0;
}
.portrait {
  display: flex; flex-direction: column; gap: 0.75rem;
}
.portrait .image-slot {
  /* square portrait slots */
  aspect-ratio: 3 / 4;
}
.portrait__name {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
.portrait__role {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin: 0;
  letter-spacing: 0.03em;
}

/* ---------- Mobile brand subtitle ---------- */
@media (max-width: 480px) {
  .site-brand__subtitle { display: none; }
  .site-brand__icon { width: 40px; height: 40px; }
}

/* ============================================================
   Admin layer — only loads when an admin is signed in.
   Edit banner, dashboard, profile, settings, flash, inline editor.
   ============================================================ */

/* ---------- Skip link (a11y) ---------- */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 10000;
  background: var(--ink); color: var(--white);
  padding: 0.5rem 1rem; text-decoration: none; font: 0.9rem/1.4 var(--font-display);
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* ---------- Edit banner ---------- */
.edit-banner {
  background: var(--ink);
  color: var(--white);
  padding: 0.5rem 1.25rem;
  font-size: 0.85rem;
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  position: sticky; top: 0; z-index: 110;
}
.edit-banner-text { min-width: 0; opacity: 0.9; }
.edit-banner-me { color: var(--white); text-decoration: underline; text-underline-offset: 2px; }
.edit-banner-me:hover { color: var(--silver-light); }
.edit-banner-links { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; }
.edit-banner-links a {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.edit-banner-links a:hover { color: var(--silver-light); }
/* Top-level strip links get real 44px hit zones (visual size unchanged —
   padding offset by negative margin). Direct children only: the dropdown
   menu items have their own padded rows. */
.edit-banner-links > a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 0.5rem 0.35rem; margin: -0.5rem -0.35rem;
}

.banner-dropdown { position: relative; display: inline-block; }
.banner-dropdown-trigger {
  appearance: none; background: transparent; border: 0;
  color: var(--white); font: inherit;
  text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer;
  padding: 0.5rem 0.35rem; margin: -0.5rem -0.35rem;
  display: inline-flex; align-items: center; gap: 0.2rem;
  min-height: 44px;
}
.banner-dropdown-trigger:hover,
.banner-dropdown-trigger:focus-visible { color: var(--silver-light); outline: none; }
.banner-dropdown-caret { font-size: 0.85em; line-height: 1; transition: transform var(--motion) var(--ease); }
.banner-dropdown-trigger[aria-expanded="true"] .banner-dropdown-caret { transform: rotate(180deg); }
.banner-dropdown-menu {
  position: absolute; top: calc(100% + 8px); left: 0;
  background: var(--ink);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius);
  padding: 0.5rem 0.4rem;
  min-width: 180px;
  z-index: 1000;
  box-shadow: 0 8px 22px rgba(0,0,0,0.45);
  display: flex; flex-direction: column;
}
.banner-dropdown-menu[hidden] { display: none; }
.edit-banner-links .banner-dropdown-menu a {
  color: var(--white);
  text-decoration: none;
  padding: 0.55rem 1.05rem;
  font-size: 0.9rem;
  line-height: 1.35;
}
.edit-banner-links .banner-dropdown-menu a:hover,
.edit-banner-links .banner-dropdown-menu a:focus-visible {
  background: rgba(255,255,255,0.1);
  outline: none;
}
@media (max-width: 768px) {
  /* Un-stick on phones: the stacked banner is ~116px tall — pinning it
     eats a fifth of the viewport and occludes the sticky site header. */
  .edit-banner { flex-direction: column; align-items: flex-start; gap: 0.4rem; padding: 0.5rem 1rem; position: static; }
  .edit-banner-text { font-size: 0.75rem; opacity: 0.8; }
  /* Anchor open menus to the links ROW, not the trigger: the old
     flex-basis:100% expansion reflowed the row mid-tap (triggers
     jumped, trailing links scattered under the open menu). A
     row-anchored full-width overlay keeps every trigger exactly
     where the thumb expects it. JS guarantees single-open. */
  .edit-banner-links { width: 100%; gap: 1rem 0.9rem; position: relative; }  /* row-gap 1rem: wrapped rows' 44px hit zones clear each other */
  .banner-dropdown { position: static; }
  /* Reorder arrows: comfortable thumb targets with a real gutter between
     the opposite-direction buttons. */
  .admin-move { gap: 8px; }
  .admin-move__btn { width: 2.75rem; min-height: 2.75rem; }
  .banner-dropdown-menu {
    position: absolute; left: 0; right: 0; top: calc(100% + 6px);
    max-height: min(60vh, 420px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* ---------- Admin flash messages ---------- */
.admin-flash {
  display: block;
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius);
  font-size: 0.92rem;
  font-weight: 500;
  margin-top: 0.85rem;
  overflow-wrap: anywhere;
}
@media (min-width: 768px) {
  .admin-flash { display: inline-block; margin-right: 0.5rem; }
}
.admin-flash--success { background: rgba(16, 185, 129, 0.12); color: #066b4f; }
.admin-flash--error { background: rgba(220, 38, 38, 0.12); color: #991b1b; }
.admin-flash--warn { background: rgba(245, 166, 35, 0.15); color: #8a6206; }

/* ---------- Placeholder note (empty states) ---------- */
.placeholder-note {
  text-align: center;
  color: var(--text-muted);
  max-width: 640px;
  margin: 2.5rem auto;
  font-size: 0.95rem;
  font-style: italic;
}
.placeholder-note a { color: var(--navy); text-decoration: underline; }

/* ---------- Admin cards ---------- */
.admin-card {
  background: var(--white);
  padding: 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  margin-bottom: 1rem;
}
.admin-card-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 1rem; }
.admin-card-head h2 { margin: 0; font-size: 1.25rem; }
.admin-card-subtitle { font-size: 0.85rem; color: var(--text-muted); font-weight: normal; }

/* ---------- Admin stats grid ---------- */
.admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
}
.stat-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  display: flex; flex-direction: column; gap: 0.25rem;
  transition: transform var(--motion) var(--ease), border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease);
}
.stat-card--link { text-decoration: none; color: inherit; cursor: pointer; }
.stat-card--link:hover, .stat-card--link:focus-visible {
  border-color: var(--navy-light);
  box-shadow: 0 8px 24px rgba(35, 64, 102, 0.08);
  transform: translateY(-1px);
  outline: none;
}
.stat-card--attention { background: rgba(245, 166, 35, 0.05); border-color: rgba(245, 166, 35, 0.3); }
.stat-number {
  font-family: var(--font-display);
  font-size: 2.5rem;
  font-weight: 600;
  margin: 0;
  color: var(--navy);
  line-height: 1;
}
.stat-label {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.35;
}

/* ---------- Welcome card ---------- */
[data-admin-welcome-section]:not([hidden]) + .section { padding-top: 1rem; }
.admin-welcome-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem 1.75rem;
  position: relative;
  max-width: 48rem;
  margin: 0 auto;
}
.admin-welcome-dismiss {
  position: absolute; top: 0.4rem; right: 0.4rem;
  background: none; border: 0;
  width: 44px; height: 44px;
  font-size: 1.4rem; line-height: 1;
  cursor: pointer; color: var(--text-soft);
  border-radius: var(--radius);
}
.admin-welcome-dismiss:hover, .admin-welcome-dismiss:focus-visible {
  background: var(--canvas-alt); color: var(--ink); outline: none;
}
.admin-welcome-lead {
  font-size: 1.05rem;
  margin: 0 0 1rem;
  color: var(--ink);
  font-weight: 500;
  padding-right: 3.25rem;
}
.admin-welcome-tasks { list-style: none; padding: 0; margin: 0 0 1rem; counter-reset: tasks; }
.admin-welcome-tasks li { margin: 0; counter-increment: tasks; }
.admin-welcome-tasks label {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.5rem 0.6rem; border-radius: var(--radius);
  cursor: pointer;
}
.admin-welcome-tasks label:hover { background: rgba(35, 64, 102, 0.04); }
.admin-welcome-tasks input[type="checkbox"] {
  width: 18px; height: 18px;
  margin: 0; accent-color: var(--navy);
}
.admin-welcome-tasks a { color: var(--navy); text-decoration: none; font-weight: 500; }
.admin-welcome-tasks a:hover { text-decoration: underline; }
.admin-welcome-tasks input:checked + a,
.admin-welcome-tasks label:has(input:checked) a {
  color: var(--text-soft); text-decoration: line-through;
}
.admin-welcome-footer { font-size: 0.85rem; color: var(--text-muted); margin: 0; }
.admin-welcome-footer a { color: var(--navy); }

/* ---------- Admin form ---------- */
.admin-form { display: flex; flex-direction: column; gap: 1rem; }
.admin-field { display: flex; flex-direction: column; gap: 0.25rem; }
.admin-field-label { font-weight: 500; font-size: 0.92rem; color: var(--text); }
.admin-field-hint { font-size: 0.8rem; color: var(--text-soft); margin-top: 0.2rem; }
.admin-field input,
.admin-field select,
.admin-field textarea {
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  background-color: var(--white);
  min-height: 44px;
  transition: border-color var(--motion) var(--ease);
}
.admin-field input:focus,
.admin-field select:focus,
.admin-field textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15);
}
.admin-form-actions { display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap; }

/* Responsive form rows — stack on mobile, grid on desktop. Used by admin edit
   forms that want 2 or 3 fields on one row at tablet+ and single-column on
   phones. Replaces scattered inline grid-template-columns styles. */
.admin-form-row {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .admin-form-row--2col { grid-template-columns: 1fr 1fr; }
  .admin-form-row--3col { grid-template-columns: repeat(3, 1fr); }
  .admin-form-row--2-1 { grid-template-columns: 2fr 1fr; }
  .admin-form-row--2-1-1 { grid-template-columns: 2fr 1fr 1fr; }
}

/* Larger content splits (dashboard panels, side-by-side lists). Larger gap
   than form rows and a higher collapse breakpoint so content doesn't cram. */
.admin-split {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  .admin-split--2col { grid-template-columns: 1fr 1fr; }
}

/* Post list — card-style rows. Replaces the old table that caused page-wide
   horizontal scroll on mobile. Columns appear at tablet+, single column on
   phone. */
.admin-post-list {
  list-style: none; padding: 0; margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--white);
  overflow: hidden;
}
.admin-post-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;   /* minmax(0): long slugs/URLs can't blow the column */
  grid-template-areas:
    "move title edit"
    "move meta edit"
    "move status edit";
  gap: 0.25rem 1rem;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--line);
  align-items: center;
}
/* Lists without reorder controls: the empty "move" column collapses to 0. */
.admin-post-row:last-child { border-bottom: none; }
.admin-post-title {
  grid-area: title;
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.admin-post-title:hover { color: var(--navy); }
.admin-post-meta {
  grid-area: meta;
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
.admin-post-status {
  grid-area: status;
  justify-self: start;
  margin-top: 0.15rem;
}
.admin-post-edit {
  grid-area: edit;
  white-space: nowrap;
}
/* Edit + Delete share one grid cell (two items can't both own grid-area:
   edit without overlapping) — same wrapper shape as .admin-move. Without
   this, the unplaced Delete form auto-flows into the empty move column
   and renders BEFORE the title. */
.admin-post-actions {
  grid-area: edit;
  align-self: center;
  display: inline-flex;
  flex-direction: column;
  gap: 0.4rem;
}
.admin-post-actions .btn { white-space: nowrap; }
@media (min-width: 768px) {
  .admin-post-row {
    grid-template-columns: auto minmax(0, 2.2fr) minmax(0, 1.4fr) auto auto;
    grid-template-areas: "move title meta status edit";
    gap: 0 1rem;
  }
  .admin-post-status { justify-self: end; margin-top: 0; }
  .admin-post-actions { flex-direction: row; }
}

/* ---------- Profile ---------- */
.admin-profile-list {
  display: grid; grid-template-columns: max-content 1fr;
  gap: 0.4rem 1.25rem; margin: 0;
}
.admin-profile-list dt {
  font-family: var(--font-display);
  text-transform: uppercase; letter-spacing: 0.08em;
  font-size: 0.78rem; color: var(--text-soft);
  align-self: center;
}
.admin-profile-list dd { margin: 0; }
.admin-chip {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  background: var(--canvas-alt);
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.admin-chip--role-owner { background: var(--navy); color: var(--white); }
.admin-chip--role-helper { background: var(--silver); color: var(--ink); }
.admin-chip--role-partner { background: var(--orange); color: var(--ink); }
.admin-chip--role-support { background: #475569; color: var(--white); } /* slate — Rendered support account; functionally owner-equivalent */
.admin-chip--audit-info { background: rgba(35, 64, 102, 0.08); color: var(--navy); }
.admin-chip--audit-warn { background: rgba(245, 166, 35, 0.18); color: #8a6206; }

/* ---------- /coatings catalog ---------- */
.coatings-filters {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.75rem;
  padding: 1rem 1.25rem;
  background: var(--canvas-alt);
  border-radius: var(--radius-lg);
}
.coatings-search input {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  min-height: 48px;
  background: var(--white);
}
.coatings-search input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15);
}
.coatings-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.coatings-chip {
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--motion) var(--ease), color var(--motion) var(--ease), border-color var(--motion) var(--ease);
  min-height: 36px;
}
.coatings-chip:hover { border-color: var(--navy-light); color: var(--navy); }
.coatings-chip--active,
.coatings-chip--active:hover,
.coatings-chip--active:focus-visible {
  background: var(--navy);
  color: var(--white);
  border-color: var(--navy);
}
.coatings-count {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
  font-family: var(--font-display);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.coatings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 1rem;
}
.coating-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.25rem 1.1rem;
  display: flex; flex-direction: column; gap: 0.5rem;
  position: relative;
  overflow: hidden;   /* clip the hover accent bar to the rounded corners */
  cursor: pointer;
  transition: border-color var(--motion) var(--ease), box-shadow var(--motion) var(--ease), transform var(--motion) var(--ease);
}
.coating-card:hover {
  border-color: var(--navy-light);
  box-shadow: 0 4px 14px rgba(35, 64, 102, 0.08);
  transform: translateY(-1px);
}
/* Paper-and-ink restraint: a thin INK rule (no color, no gradient) draws in
   on hover — a quiet catalog-card cue, not a flourish. Decorative only
   (pointer-events: none) so it never intercepts the stretched-link click. */
.coating-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: var(--navy);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--motion) var(--ease);
  pointer-events: none;
}
.coating-card:hover::before { transform: scaleX(1); }
.coating-card[hidden] { display: none; }
.coating-card__title { font-family: var(--font-display); font-size: 1.05rem; margin: 0; line-height: 1.25; color: var(--ink); }
.coating-card__title a { color: inherit; text-decoration: none; }
.coating-card:hover .coating-card__title a { color: var(--navy); }
/* Stretched-link pattern: the title <a> gets an absolutely-positioned
   ::after that covers the whole card. Any click on the card area —
   composition, processes, similar-to — navigates to the detail page.
   Nested interactive elements (Edit button) bump their z-index so
   they stay clickable. */
.coating-card__title a::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 1;
}
.coating-card__title a:focus-visible {
  outline: none;
}
.coating-card:has(.coating-card__title a:focus-visible) {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}
.coating-card__composition {
  font-family: ui-monospace, monospace;
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 0;
  overflow-wrap: anywhere;
}
.coating-card__processes {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; gap: 0.3rem;
}
.coating-card__processes li {
  padding: 0.2rem 0.55rem;
  background: var(--canvas-alt);   /* neutral paper pill — ink text does the work */
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--navy);
}
.coating-card__processes--lg li { padding: 0.3rem 0.75rem; font-size: 0.82rem; }
.coating-card__similar {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 0;
  overflow-wrap: anywhere;
}
.coating-card__similar strong { color: var(--text); font-weight: 600; }
.coating-card__edit {
  margin-top: 0.35rem;
  align-self: flex-start;
  position: relative;
  z-index: 2;
}
.coatings-empty {
  text-align: center;
  color: var(--text-muted);
  margin: 2rem auto 0;
  font-style: italic;
}

/* Coating-detail enrichment layout — technical-data grid, pros/cons
   columns, facet grid (applications/wear/industries/substrates),
   sources block. Only appears on materials with enrichment data. */
.coating-spec-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem 1.5rem;
  margin: 1rem 0 0;
}
@media (min-width: 640px) {
  .coating-spec-grid {
    grid-template-columns: minmax(10rem, max-content) 1fr;
  }
}
.coating-spec-grid dt {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-soft);
  align-self: baseline;
}
.coating-spec-grid dd {
  margin: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}
.coating-pros-cons {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
}
@media (min-width: 720px) {
  .coating-pros-cons { grid-template-columns: 1fr 1fr; }
}
.coating-pros-cons ul {
  line-height: 1.6;
  padding-left: 1.25rem;
}
.coating-pros-cons li { margin-bottom: 0.5rem; }
.coating-facet-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
@media (min-width: 720px) {
  .coating-facet-grid { grid-template-columns: 1fr 1fr; }
}
.coating-facet-grid h3 {
  font-size: 0.9rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-soft);
  font-family: var(--font-display);
  margin-bottom: 0.5rem;
}
.coating-regulatory-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.coating-regulatory-list li {
  padding: 0.6rem 0.85rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
  color: var(--text);
}
.coating-sources-list {
  list-style: none;
  padding: 0;
  margin: 0.75rem 0 0;
  overflow-wrap: anywhere;
}
.coating-sources-list li {
  padding: 0.85rem 0;
  border-top: 1px solid var(--line);
}
.coating-sources-list li:first-child { border-top: 0; }
.coating-sources-list a {
  color: var(--navy);
  font-weight: 500;
}
.coating-source-quote {
  color: var(--text-muted);
  font-size: 0.9rem;
  font-style: italic;
  margin: 0.3rem 0 0;
}

/* ---------- /admin/audit log view ----------
   Owner-only read-only window into hts_audit_log. Card-row list that
   collapses to stack on mobile (same pattern as .admin-post-list). */
.admin-audit-filters {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1rem 1.25rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  margin-bottom: 1.5rem;
}
@media (min-width: 640px) {
  .admin-audit-filters { grid-template-columns: 1fr 1fr auto; align-items: end; }
}
.admin-audit-filter-actions { display: flex; gap: 0.5rem; align-items: center; }
.admin-audit-table {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--white);
  overflow: hidden;
}
/* Column-header row. Hidden on mobile (cards show inline col labels
   instead); visible as a table header at >=900px. Uses the same grid
   template as .admin-audit-row so columns line up cleanly. */
.admin-audit-head { display: none; }
@media (min-width: 900px) {
  .admin-audit-head {
    display: grid;
    grid-template-columns: 8rem minmax(10rem, 1.3fr) 12rem minmax(8rem, 1fr) minmax(10rem, 1.4fr);
    gap: 0 1rem;
    padding: 0.65rem 1rem;
    background: var(--canvas-alt);
    border-bottom: 1px solid var(--line);
    font-family: var(--font-display);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-soft);
  }
}
.admin-audit-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--line);
  align-items: center;
}
.admin-audit-row:last-child { border-bottom: none; }
@media (min-width: 900px) {
  .admin-audit-row {
    grid-template-columns: 8rem minmax(10rem, 1.3fr) 12rem minmax(8rem, 1fr) minmax(10rem, 1.4fr);
    gap: 0 1rem;
  }
}
/* Mobile col labels — tiny caption over each cell so stacked rows
   stay readable without needing the table header. Hidden >=900px. */
.admin-audit-col-label {
  display: block;
  font-family: var(--font-display);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: 0.15rem;
}
@media (min-width: 900px) {
  .admin-audit-col-label { display: none; }
}
.admin-audit-when {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-soft);
  white-space: nowrap;
}
.admin-audit-who strong { color: var(--ink); }
.admin-audit-sub, .admin-audit-muted { color: var(--text-muted); font-size: 0.82rem; }
.admin-audit-who .admin-audit-sub { margin-left: 0.35rem; }
.admin-audit-what { min-width: 0; }
.admin-audit-what .admin-chip {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-audit-on a { color: var(--navy); text-decoration: none; }
.admin-audit-on a:hover { text-decoration: underline; }
.admin-audit-meta { min-width: 0; }
.admin-audit-meta code {
  font-family: ui-monospace, monospace;
  font-size: 0.78rem;
  color: var(--text-muted);
  background: var(--canvas-alt);
  padding: 0.15rem 0.45rem;
  border-radius: 3px;
  overflow-wrap: anywhere;
  display: inline-block;
  max-width: 100%;
}
.admin-audit-pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 1.25rem;
}

/* ---------- Help (markdown) + Public prose (markdown-rendered body) ----------
   .admin-help drives /admin/help, .prose drives renderContent() output on
   service-detail / problem-detail / industry-detail / future markdown
   pages. Shared rules keep both sources visually consistent. */
/* Some imported Shopify posts contain long URLs (and the occasional
   parts-number string) that won't break at spaces. Without this they
   blow past the viewport on mobile and stretch the page horizontally.
   overflow-wrap: anywhere only kicks in when a token would otherwise
   overflow, so normal prose still wraps at word boundaries first. */
.admin-help, .prose { overflow-wrap: anywhere; }
.admin-help img, .prose img { max-width: 100%; height: auto; }
.admin-help pre, .prose pre { max-width: 100%; overflow-x: auto; }
.admin-help h2,
.prose h2 { margin-top: 2.5rem; }
.admin-help h3,
.prose h3 { margin-top: 1.75rem; }
.admin-help ul, .admin-help ol,
.prose ul, .prose ol { padding-left: 1.5rem; line-height: 1.7; margin-bottom: 1rem; }
.admin-help li,
.prose li { margin-bottom: 0.35rem; }
.admin-help p,
.prose p { line-height: 1.7; margin-bottom: 1rem; }
.admin-help code,
.prose code {
  font-family: ui-monospace, monospace;
  font-size: 0.88em;
  padding: 0.1rem 0.35rem;
  background: var(--canvas-alt);
  border-radius: 3px;
}
.admin-help blockquote,
.prose blockquote {
  border-left: 3px solid var(--silver);
  padding-left: 1rem;
  color: var(--text-muted);
  font-style: italic;
  margin: 1.25rem 0;
}
.admin-help hr,
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 2rem 0; }
.admin-help a,
.prose a { color: var(--navy); text-decoration: underline; }
.prose > :first-child { margin-top: 0; }

/* ---------- Inline editor ---------- */
/* Inline image-slot editor: hoverable affordance + hero pill.
   Active only in edit mode (body.edit-mode), so public visitors see
   nothing. */
body.edit-mode [data-image-slot] {
  cursor: pointer;
  position: relative;
}
body.edit-mode [data-image-slot]::after {
  content: '✎  Change image';
  position: absolute;
  inset: auto 0.75rem 0.75rem auto;
  background: rgba(17, 17, 17, 0.78);
  color: #fff;
  padding: 0.45rem 0.8rem;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity var(--motion) var(--ease);
  pointer-events: none;
  z-index: 3;
}
body.edit-mode [data-image-slot]:hover::after,
body.edit-mode [data-image-slot]:focus-visible::after {
  opacity: 1;
}
body.edit-mode [data-image-slot]:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/* Floating pill for hero sections — hero bg is a gradient + URL
   combo that's harder to swap inline, so we reload on save. Pill
   sits top-right of the hero. */
.hero-edit-pill {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  z-index: 3;
  background: rgba(17, 17, 17, 0.78);
  color: #fff;
  border: 0;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius);
  font: 500 0.72rem/1 var(--font-display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--motion) var(--ease);
}
.hero-edit-pill:hover,
.hero-edit-pill:focus-visible {
  background: var(--navy);
  outline: none;
}

body.edit-mode [data-editable].hts-editable {
  outline: 1px dashed rgba(35, 64, 102, 0.45);
  outline-offset: 2px;
  cursor: pointer;
  border-radius: 2px;
}
body.edit-mode [data-editable].hts-editable:hover,
body.edit-mode [data-editable].hts-editable:focus-visible {
  outline: 2px dashed var(--navy);
  outline-offset: 3px;
  background: rgba(35, 64, 102, 0.04);
  outline-style: dashed;
}
/* Over the navy home hero and photo page-heroes the navy dashes vanish
   into the dark background — exactly where the banner headline sits.
   Light color-only override (width/offset/style still come from the
   base rules above); mirrors the .page-hero--with-image .btn--ghost
   white-on-dark treatment. */
body.edit-mode .hero [data-editable].hts-editable,
body.edit-mode .page-hero--with-image [data-editable].hts-editable {
  outline-color: rgba(255, 255, 255, 0.65);
}
body.edit-mode .hero [data-editable].hts-editable:hover,
body.edit-mode .hero [data-editable].hts-editable:focus-visible,
body.edit-mode .page-hero--with-image [data-editable].hts-editable:hover,
body.edit-mode .page-hero--with-image [data-editable].hts-editable:focus-visible {
  outline-color: var(--white);
  background: rgba(255, 255, 255, 0.08);
}
body.edit-mode [data-editable].hts-editing {
  outline: none;
  background: none;
}
body.edit-mode [data-editable].hts-editable-locked {
  outline: 1px dashed rgba(122, 122, 122, 0.4);
  outline-offset: 2px;
  cursor: not-allowed;
  opacity: 0.7;
}
.hts-edit-wrapper {
  display: flex; flex-direction: column; gap: 0.4rem;
  margin: 0.4rem 0;
  padding: 0.6rem;
  background: var(--canvas-alt);
  border-radius: var(--radius);
  border: 1px solid var(--navy-light);
  box-shadow: 0 2px 8px rgba(35, 64, 102, 0.1);
}
.hts-edit-input {
  font: inherit;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  width: 100%;
  box-sizing: border-box;
}
.hts-edit-input:focus { outline: none; border-color: var(--navy); box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15); }
.hts-edit-textarea { resize: vertical; min-height: 4rem; line-height: 1.5; font-family: inherit; }
.hts-edit-toolbar { display: flex; gap: 0.25rem; }
.hts-edit-tb-btn {
  appearance: none; background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); cursor: pointer;
  padding: 0.3rem 0.65rem; font: 600 0.85rem var(--font-display);
  color: var(--text); min-height: 44px;
}
.hts-edit-tb-btn:hover { background: var(--canvas-alt); border-color: var(--navy-light); }
.hts-edit-actions { display: flex; gap: 0.5rem; }
.hts-edit-save, .hts-edit-cancel {
  appearance: none; cursor: pointer;
  padding: 0.45rem 1rem; border-radius: var(--radius);
  font: 500 0.85rem var(--font-display); text-transform: uppercase; letter-spacing: 0.05em;
  border: 2px solid transparent; min-height: 44px;
}
.hts-edit-save { background: var(--navy); color: var(--white); border-color: var(--navy); }
.hts-edit-save:hover { background: var(--navy-dark); border-color: var(--navy-dark); }
.hts-edit-save:disabled { background: var(--text-soft); border-color: var(--text-soft); cursor: wait; }
.hts-edit-cancel { background: transparent; color: var(--text); border-color: var(--line); }
.hts-edit-cancel:hover { background: var(--canvas-alt); }
.hts-edit-error {
  font-size: 0.85rem; color: var(--error); margin-top: 0.2rem;
  padding: 0.4rem 0.6rem; background: rgba(220, 38, 38, 0.08);
  border-radius: var(--radius);
}
.hts-toast {
  position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 9999;
  background: var(--ink); color: var(--white);
  padding: 0.75rem 1.2rem;
  border-radius: var(--radius);
  font-family: var(--font-display); font-size: 0.92rem;
  letter-spacing: 0.04em;
  opacity: 0; transform: translateY(0.5rem);
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
  pointer-events: none;
}
.hts-toast.visible { opacity: 1; transform: translateY(0); }

/* ---------- Settings accordion ---------- */
.settings-accordion {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  margin-bottom: 0.75rem;
  overflow: hidden;
}
.settings-accordion summary {
  padding: 1rem 1.25rem;
  cursor: pointer; user-select: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
  list-style: none;
  display: flex; align-items: center; justify-content: space-between;
}
.settings-accordion summary::-webkit-details-marker { display: none; }
.settings-accordion summary::after {
  content: '\25BE';
  font-size: 0.85em;
  color: var(--text-soft);
  transition: transform var(--motion) var(--ease);
}
.settings-accordion[open] summary::after { transform: rotate(180deg); }
.settings-accordion summary:hover { background: var(--canvas-alt); }
.settings-accordion-body {
  padding: 0.5rem 1.25rem 1.25rem;
  border-top: 1px solid var(--line);
}
.settings-grid { display: grid; grid-template-columns: 1fr; gap: 0.25rem 1.25rem; align-items: baseline; padding-top: 0.75rem; }
@media (min-width: 640px) {
  .settings-grid { grid-template-columns: minmax(8rem, max-content) 1fr; gap: 0.5rem 1.25rem; }
}
.settings-label {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--text-soft);
}
.settings-value { color: var(--text); overflow-wrap: anywhere; min-width: 0; }
.settings-value:empty::before {
  content: '— not set —';
  color: var(--text-soft); font-style: italic;
}
.settings-note { font-size: 0.85rem; color: var(--text-muted); margin: 0.5rem 0 0; }
.settings-note--inline { background: var(--canvas-alt); padding: 0.6rem 0.85rem; border-radius: var(--radius); margin-bottom: 0.75rem; }
.settings-note code { font-family: ui-monospace, monospace; font-size: 0.88em; padding: 0.1rem 0.3rem; background: var(--white); border-radius: 3px; }

/* Image-picker-backed settings fields (Hero Images + Photography slots).
   Replaces the old URL-paste text inputs — Ashley clicks Choose image,
   the shared HtsImagePicker opens, and the selected image's URL is
   PATCHed into the settings.* row via /api/content. */
.settings-image-fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding-top: 0.5rem;
}
.settings-image-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--canvas);
}
.settings-image-label {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--text-soft);
}
.settings-image-widget {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.settings-image-thumb {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-dark) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--silver-light);
}
.settings-image-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.settings-image-empty {
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7);
  text-align: center;
  padding: 0 0.3rem;
}
.settings-image-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}
.settings-image-status {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-left: 0.25rem;
}
.settings-image-status--success { color: var(--success); font-weight: 600; }
.settings-image-status--error { color: var(--error); font-weight: 600; }

/* ---------- /admin/users table + invite ---------- */
.admin-users-table {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.admin-user-row {
  display: grid;
  grid-template-columns: minmax(200px, 2.4fr) 1.1fr 1fr 0.9fr minmax(200px, 1.5fr);
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--line);
  align-items: center;
}
.admin-user-row:last-child { border-bottom: none; }
.admin-user-row--inactive { opacity: 0.55; background: var(--canvas-alt); }
.admin-user-row--self { background: rgba(35, 64, 102, 0.04); }
.admin-user-cell { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.admin-user-cell--name { gap: 0.85rem; }
.admin-user-cell--actions { justify-content: flex-end; }
.admin-user-avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--white);
  font: 600 0.85rem var(--font-display);
  letter-spacing: 0.04em;
  flex-shrink: 0;
}
.admin-user-name { margin: 0; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 0.5rem; }
.admin-user-you {
  font-family: var(--font-display);
  font-size: 0.7rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.1em;
  background: var(--canvas-alt); color: var(--text-muted);
  padding: 0.1rem 0.45rem; border-radius: 3px;
}
.admin-user-meta { margin: 0.15rem 0 0; font-size: 0.85rem; color: var(--text-muted); }
.admin-user-meta--warn { color: var(--warn); font-weight: 500; }
.admin-inline-form { display: inline-flex; margin: 0; gap: 0.4rem; align-items: center; }
.admin-role-select {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  background: var(--white);
  min-height: 40px;
}
.btn--sm { padding: 0.45rem 0.9rem; min-height: 40px; font-size: 0.8rem; }

@media (max-width: 1024px) {
  .admin-user-row {
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }
  .admin-user-cell--actions { justify-content: flex-start; flex-wrap: wrap; }
}

/* Password callout (after invite or reset) */
.admin-password-callout {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.5rem;
}
.admin-password-callout-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.75rem; }
.admin-password-callout-warn { font-size: 0.8rem; color: #8a6206; font-weight: 500; }
.admin-password-row { display: flex; align-items: center; gap: 0.5rem; margin: 0.5rem 0 0.75rem; flex-wrap: wrap; }
.admin-password-pill {
  font-family: ui-monospace, monospace;
  font-size: 1.05rem;
  padding: 0.5rem 0.85rem;
  background: var(--canvas-alt);
  border-radius: var(--radius);
  border: 1px dashed var(--orange);
  user-select: all;
  flex: 1;
  min-width: 12rem;
}
.admin-password-hand-off { font-size: 0.85rem; color: var(--text-muted); margin: 0; }

/* ============================================================
   Image pipeline — library, upload, focal-point editor, picker
   Ported from retrofit; tokens translated to HTS's navy palette.
   ============================================================ */

.image-upload-form {
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  margin-bottom: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space);
  max-width: 40rem;
}
.image-upload-field { display: flex; flex-direction: column; gap: 0.35rem; }
.image-upload-label {
  font-family: var(--font-display);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.image-upload-form input[type="file"],
.image-upload-form input[type="text"] {
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--canvas);
  font: inherit;
  color: var(--text);
}
.image-upload-form input[type="file"] { cursor: pointer; }
.image-upload-form input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15);
}
.image-upload-form button[type="submit"] { align-self: flex-start; }
/* iOS Safari blows containers wider than the viewport once a filename
   shows inside a native file input (same fix as .contact-form__photo). */
.image-upload-field { min-width: 0; max-width: 100%; }
.image-upload-form input[type="file"],
.hts-picker-upload-label input[type="file"] {
  width: 100%;
  max-width: 100%;
  min-width: 0;
}
.image-upload-status {
  font-size: 0.9rem;
  color: var(--text-muted);
  min-height: 1.2em;
}
.image-upload-status--success { color: var(--success); font-weight: 600; }
.image-upload-status--error { color: var(--error); font-weight: 600; }
.image-upload-progress {
  width: 100%;
  height: 6px;
  background: var(--canvas-alt);
  border-radius: 999px;
  overflow: hidden;
}
.image-upload-progress[hidden] { display: none; }
.image-upload-progress-bar {
  height: 100%;
  width: 0%;
  background: var(--orange);
  border-radius: 999px;
  transition: width 180ms linear;
}
/* Indeterminate state: a sliding chunk that loops while we wait for the
   server response. Used when byte-level progress isn't available (fetch). */
.image-upload-progress--indeterminate .image-upload-progress-bar {
  width: 40%;
  animation: htsIndeterminateSlide 1.2s ease-in-out infinite;
}
@keyframes htsIndeterminateSlide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

.image-library-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space);
  margin: var(--space-lg) 0 var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 2px solid var(--navy);
}
.image-library-count {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-family: var(--font-display);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.image-library-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-md);
}
@media (min-width: 768px) {
  .image-library-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
}
.image-library-grid[hidden] { display: none; }
.image-card {
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin: 0;
}
.image-card img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-bottom: 1px solid var(--line);
}
.image-card figcaption {
  padding: var(--space-sm) var(--space) var(--space);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
}
.image-card-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.image-card-dims {
  color: var(--text-muted);
  font-family: var(--font-display);
  letter-spacing: 0.05em;
  font-size: 0.75rem;
}
.image-card-actions {
  display: flex;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}
.image-card-edit,
.image-card-delete {
  background: transparent;
  border: 1px solid var(--line);
  font-size: 0.75rem;
  padding: 0.5rem 0.85rem;
  min-height: 40px;
  border-radius: var(--radius);
  font-family: var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.2s ease;
}
.image-card-edit { color: var(--navy); }
.image-card-edit:hover:not(:disabled) {
  background: rgba(35, 64, 102, 0.08);
  border-color: var(--navy);
}
.image-card-delete { color: var(--error); }
.image-card-delete:hover:not(:disabled) {
  background: rgba(220, 38, 38, 0.08);
  border-color: var(--error);
}
.image-card-delete:disabled { opacity: 0.6; cursor: wait; }

/* Focal-point editor modal */

.image-editor {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space);
  touch-action: manipulation;
}
.image-editor[hidden] { display: none; }
.image-editor-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(17, 17, 17, 0.72);
}
.image-editor-panel {
  position: relative;
  background: var(--canvas);
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  max-width: 48rem;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.image-editor-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space) var(--space-md);
  border-bottom: 1px solid var(--line);
}
.image-editor-head h2 { margin: 0; font-size: 1.15rem; }
.image-editor-close {
  background: transparent;
  border: none;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius);
}
.image-editor-close:hover { color: var(--navy); }
.image-editor-body {
  padding: var(--space) var(--space-md) var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space);
}
.image-editor-preview {
  position: relative;
  background: var(--canvas-alt);
  border-radius: var(--radius);
  overflow: hidden;
  max-height: 40vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
.image-editor-preview img {
  display: block;
  max-width: 100%;
  max-height: 40vh;
  width: auto;
  height: auto;
  cursor: crosshair;
  user-select: none;
}
@media (min-width: 768px) {
  .image-editor-preview { max-height: 55vh; }
  .image-editor-preview img { max-height: 55vh; }
}
.image-editor-focal {
  position: absolute;
  width: 26px;
  height: 26px;
  border: 2px solid var(--white);
  background: rgba(245, 166, 35, 0.55);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 0 2px rgba(35, 64, 102, 0.85), 0 4px 12px rgba(0, 0, 0, 0.35);
  /* pointer-events: none so clicks pass through to the <img> below —
     without this the crosshair absorbs the click and focal never moves */
  pointer-events: none;
  transition: left 0.12s ease, top 0.12s ease;
}
.image-editor-focal::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 4px; height: 4px;
  background: var(--white);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.image-editor-hint { color: var(--text-muted); font-size: 0.88rem; margin: 0; }
.image-editor-field { display: flex; flex-direction: column; gap: 0.3rem; }
.image-editor-label {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.image-editor-field textarea {
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--canvas);
  font: inherit;
  font-family: var(--font-sans);
  color: var(--text);
  resize: vertical;
  min-height: 70px;
}
.image-editor-field textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15);
}
.image-editor-hint-inline { font-size: 0.8rem; color: var(--text-muted); font-style: italic; overflow-wrap: anywhere; }
.image-editor-actions {
  display: flex; flex-wrap: wrap; gap: var(--space-sm);
  position: sticky; bottom: 0;
  background: var(--canvas);
  padding-top: var(--space-sm);
  margin-top: var(--space-xs);
  border-top: 1px solid var(--line);
}
.image-editor-status { min-height: 1.2em; font-size: 0.9rem; margin: 0; color: var(--text-muted); }
.image-editor-status--success { color: var(--success); font-weight: 600; }
.image-editor-status--error { color: var(--error); font-weight: 600; }

/* Reusable image picker modal (opens from admin forms) */

@keyframes htsFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.hts-picker-overlay {
  position: fixed;
  inset: 0;
  background: rgba(17, 17, 17, 0.72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-md) var(--space);
  overflow-y: auto;
  animation: htsFadeIn 0.15s ease-out;
  touch-action: manipulation;
}
body.hts-picker-open { overflow: hidden; }

.hts-picker-modal {
  background: var(--canvas);
  border-radius: var(--radius-lg);
  border-top: 4px solid var(--navy);
  max-width: 60rem;
  width: 100%;
  max-height: calc(100vh - var(--space-lg));
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}
.hts-picker-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space) var(--space-md);
  border-bottom: 1px solid var(--line);
  background: var(--canvas-alt);
}
.hts-picker-header h2 { font-size: 1.25rem; margin: 0; }
.hts-picker-close {
  background: none;
  border: 0;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius);
}
.hts-picker-close:hover { color: var(--navy); }

.hts-picker-upload {
  padding: var(--space) var(--space-md);
  background: var(--canvas-alt);
  border-bottom: 1px solid var(--line);
}
.hts-picker-upload-form {
  display: flex;
  gap: var(--space-sm);
  align-items: flex-end;
  flex-wrap: wrap;
}
.hts-picker-upload-label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 1;
  min-width: 14rem;
}
.hts-picker-upload-label > span {
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hts-picker-upload-label input[type="file"],
.hts-picker-alt {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--canvas);
  font: inherit;
  color: var(--text);
}
.hts-picker-alt { flex: 2; min-width: 12rem; }
.hts-picker-upload-status {
  flex-basis: 100%;
  font-size: 0.85rem;
  color: var(--text-muted);
  margin: 0;
  min-height: 1.2em;
}
.hts-picker-upload-status--success { color: var(--success); font-weight: 600; }
.hts-picker-upload-status--error { color: var(--error); font-weight: 600; }

.hts-picker-library { padding: var(--space) var(--space-md); }
.hts-picker-library-header { margin-bottom: var(--space-sm); }
.hts-picker-library-header h3 {
  font-family: var(--font-display);
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hts-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-sm);
}
/* Preemptive [hidden] override — display:grid beats UA [hidden]{display:none}
   by source-order specificity, so grid items refuse to hide without this.
   See PATTERNS-FROM-RETROFIT.md "Critical CSS trap". */
.hts-picker-grid[hidden] { display: none; }
.hts-picker-loading,
.hts-picker-empty,
.hts-picker-error {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--space-md);
  color: var(--text-muted);
  font-style: italic;
}
.hts-picker-error { color: var(--error); }
.hts-picker-tile {
  display: flex;
  flex-direction: column;
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: 0;
  background: var(--canvas);
  cursor: pointer;
  overflow: hidden;
  transition: all 0.2s ease;
}
.hts-picker-tile:hover {
  border-color: var(--navy);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.hts-picker-tile--current {
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(245, 166, 35, 0.25);
}
.hts-picker-tile[hidden] { display: none; }
.hts-picker-tile img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  display: block;
}
.hts-picker-tile-name {
  padding: 0.4rem 0.5rem;
  font-size: 0.75rem;
  color: var(--text-muted);
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  text-align: left;
}
.hts-picker-tile-broken {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--canvas-alt);
  color: var(--text-muted);
}

/* Admin form: image picker trigger (replaces Image URL text input) */

.admin-image-picker {
  display: flex;
  align-items: center;
  gap: var(--space);
  padding: var(--space-sm);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--canvas);
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.admin-image-picker:hover {
  border-color: var(--navy);
  background: var(--canvas-alt);
}
.admin-image-picker-thumb {
  width: 4rem;
  height: 4rem;
  flex-shrink: 0;
  border-radius: var(--radius);
  /* Navy gradient placeholder when empty — same brand language as the
     public-facing image-slot. Camera icon centered via the SVG child. */
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-dark) 100%);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--silver-light);
}
.admin-image-picker-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.admin-image-picker-thumb-icon {
  width: 1.75rem;
  height: 1.75rem;
  opacity: 0.75;
}
.admin-image-picker-label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 1;
  min-width: 0;
}
.admin-image-picker-title { font-weight: 600; color: var(--navy); overflow-wrap: anywhere; }
/* Audit "Who" cell holds visitor-typed emails (quote-form actors) — wrap them. */
.admin-audit-who strong { overflow-wrap: anywhere; }
.admin-image-picker-hint { font-size: 0.85rem; color: var(--text-muted); }
.admin-image-picker-clear {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--error);
  font-size: 0.75rem;
  padding: 0.5rem 0.85rem;
  min-height: 40px;
  border-radius: var(--radius);
  font-family: var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}
.admin-image-picker-clear:hover { background: rgba(220, 38, 38, 0.08); }

/* ---------- /notes/:slug prev/next navigation ---------- */
.note-nav-pair {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}
.note-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex: 1 1 15rem;
  min-width: 0;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--canvas-alt);
  color: inherit;
  text-decoration: none;
  transition: background var(--motion) var(--ease),
              border-color var(--motion) var(--ease),
              transform var(--motion) var(--ease);
}
.note-nav:hover {
  background: var(--canvas);
  border-color: var(--navy);
  transform: translateY(-1px);
}
.note-nav:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}
.note-nav__thumb {
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: var(--radius);
  background-color: var(--navy-dark);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
.note-nav__body {
  flex: 1 1 auto;
  min-width: 0;
}
.note-nav__label {
  display: block;
  font-family: var(--font-display);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-muted);
  margin-bottom: 0.3rem;
}
.note-nav__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: 600;
  line-height: 1.35;
}

/* ---------- Markdown editor (admin) ---------- */
.md-toolbar {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.5rem 0.6rem;
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
  flex-wrap: wrap;
}
.md-toolbar__spacer { flex: 1; }
.md-btn {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.4rem 0.7rem;
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  cursor: pointer;
  min-height: 36px;
  min-width: 36px;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease);
}
.md-btn:hover { background: var(--canvas-alt); border-color: var(--navy); }
.md-btn:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.md-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.md-btn--preview { background: var(--navy); color: #fff; border-color: var(--navy); }
.md-btn--preview:hover { background: var(--navy-dark); border-color: var(--navy-dark); }

textarea[data-md-editor] {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  border-top: none;
}
textarea.md-drag-over {
  outline: 3px dashed var(--orange);
  outline-offset: -3px;
  background: rgba(245, 166, 35, 0.06);
}

.md-preview {
  border: 1px solid var(--line);
  border-top: none;
  border-radius: 0 0 var(--radius) var(--radius);
  padding: 1.25rem 1.5rem;
  background: var(--canvas);
  min-height: 16rem;
  max-height: 40rem;
  overflow: auto;
  line-height: 1.65;
}
.md-preview img { max-width: 100%; height: auto; border-radius: var(--radius); }
.md-preview h2 { margin-top: 1.5rem; }
.md-preview h3 { margin-top: 1.25rem; }
.md-preview p { margin: 0.75em 0; }
.md-preview blockquote {
  border-left: 3px solid var(--navy);
  padding-left: 1rem;
  color: var(--text-muted);
  margin: 1rem 0;
}

@media (max-width: 30rem) {
  .md-toolbar { gap: 0.2rem; padding: 0.4rem; }
  .md-btn { padding: 0.4rem 0.55rem; min-width: 44px; min-height: 44px; font-size: 0.8rem; }
}

/* ---------- Select chevron: site-wide custom dropdown arrow ----------
   Native <select> chevrons sit flush with the right border. Custom SVG
   chevron + appearance: none gives the arrow some breathing room from
   the edge across desktop and iOS Safari, plus consistent rendering
   on every form (contact + admin + filter dropdowns). The :focus and
   :disabled overrides preserve color tokens already in use. */
select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23555555' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  padding-right: 2.4rem;
}
select::-ms-expand { display: none; }

/* ---------- LinkedIn cross-post teaser (admin) ----------
   Disabled-state card flagging that this capability isn't wired
   up yet. Reads as informational, not promotional. */
.linkedin-teaser {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  padding: 0.95rem 1.1rem;
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.linkedin-teaser__lock {
  font-size: 1.2rem;
  line-height: 1.3;
  opacity: 0.55;
}
.linkedin-teaser__body { flex: 1; min-width: 0; }
.linkedin-teaser__title {
  margin: 0 0 0.25rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
}
.linkedin-teaser__badge {
  margin-left: 0.4rem;
  vertical-align: middle;
  background: var(--canvas);
  color: var(--text-muted);
  border: 1px solid var(--line);
  font-weight: 500;
}
.linkedin-teaser__pitch {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.88rem;
  line-height: 1.55;
}

/* ---------- Admin analytics dashboard (/admin/analytics) ----------
   Three tiers: 5 KPI cards, 3 trend tiles, 3 activity tables. Built
   off the existing .stat-card foundation but with a delta + sparkline
   slot. Mobile stacks vertically; desktop spreads to 5-up / 3-up. */
.analytics-preview-banner {
  /* Navy-tinted (rather than orange) so it doesn't visually rhyme
     with the orange sparkline fills inside the KPI cards. */
  margin: 1rem 0 0;
  padding: 0.85rem 1rem;
  background: rgba(35, 64, 102, 0.06);
  border: 1px solid rgba(35, 64, 102, 0.35);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 0.92rem;
  line-height: 1.5;
}

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1rem;
}
.kpi-card {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1.1rem 1.25rem;
  background: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--text);
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease), transform var(--motion) var(--ease);
}
.kpi-card--link:hover {
  background: var(--canvas);
  border-color: var(--navy-light);
  transform: translateY(-1px);
}
.kpi-card__label {
  margin: 0;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.kpi-card__row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.kpi-card__value {
  margin: 0;
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--ink);
}
.kpi-card__delta {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  white-space: nowrap;
}
.kpi-card__delta--up { color: #2f7d3a; }
.kpi-card__delta--down { color: #b3441a; }
.kpi-card__spark {
  width: 100%;
  height: 24px;
  display: block;
  margin-top: 0.2rem;
}
.kpi-card__hint {
  margin: 0;
  font-size: 0.78rem;
  color: var(--text-soft);
  line-height: 1.4;
}

.trend-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.25rem;
}
.trend-tile {
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.15rem 1.25rem 1.25rem;
}
.trend-tile__header {
  margin-bottom: 0.85rem;
}
.trend-tile__title {
  margin: 0 0 0.15rem;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
}
.trend-tile__window {
  margin: 0;
  font-size: 0.78rem;
  color: var(--text-soft);
  font-family: var(--font-display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.trend-tile__caption {
  margin: 0.6rem 0 0;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.trend-tile__legend {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0;
  display: flex;
  gap: 0.85rem;
  flex-wrap: wrap;
  font-size: 0.78rem;
  color: var(--text-muted);
}
.trend-tile__swatch {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  margin-right: 0.3rem;
  vertical-align: middle;
}
.trend-tile__swatch--orange { background: var(--orange); }
.trend-tile__swatch--navy { background: var(--navy-light); }

.trend-bars {
  display: flex;
  align-items: flex-end;
  gap: 0.3rem;
  height: 80px;
}
.trend-bars__slot {
  flex: 1;
  display: flex;
  align-items: flex-end;
  height: 100%;
}
.trend-bars__bar {
  width: 100%;
  background: var(--orange);
  border-radius: 2px 2px 0 0;
  min-height: 2px;
}

.trend-line {
  width: 100%;
  height: 80px;
  display: block;
}

.trend-rank {
  list-style: none;
  margin: 0;
  padding: 0;
}
.trend-rank__row {
  display: grid;
  grid-template-columns: 1fr 5rem 2.5rem;
  gap: 0.6rem;
  align-items: center;
  padding: 0.35rem 0;
  font-size: 0.88rem;
}
.trend-rank__row + .trend-rank__row { border-top: 1px solid var(--line); }
.trend-rank__name {
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.trend-rank__name:hover { color: var(--navy); }
.trend-rank__bar {
  position: relative;
  height: 6px;
  background: var(--canvas-alt);
  border-radius: 3px;
  overflow: hidden;
}
.trend-rank__bar > span {
  display: block;
  height: 100%;
  background: var(--navy-light);
}
.trend-rank__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text-muted);
}

.activity-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.25rem;
}
.activity-tile {
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.15rem 1.25rem 1.25rem;
}
.activity-tile__header { margin-bottom: 0.65rem; }
.activity-tile__title {
  margin: 0 0 0.15rem;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
}
.activity-tile__window {
  margin: 0;
  font-size: 0.78rem;
  color: var(--text-soft);
  font-family: var(--font-display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.activity-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}
.activity-table thead th {
  text-align: left;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-soft);
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--line);
}
.activity-table tbody tr + tr td { border-top: 1px solid var(--line); }
.activity-table td { padding: 0.5rem 0; vertical-align: top; }
.activity-table__cell-grow {
  width: 100%;
  /* Long URL paths and unbroken query strings would otherwise blow
     out the layout on a 375px-wide phone. anywhere lets the browser
     break inside a token only when it would overflow. */
  overflow-wrap: anywhere;
  word-break: break-word;
}
.activity-table__cell-grow a {
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
}
.activity-table__cell-grow a:hover { color: var(--navy); }
.activity-table__path {
  display: block;
  font-size: 0.74rem;
  color: var(--text-soft);
  font-family: ui-monospace, monospace;
  margin-top: 0.1rem;
  overflow-wrap: anywhere;
}

.trend-tile__empty {
  margin: 0.5rem 0 0;
  padding: 1rem 0.5rem;
  font-size: 0.88rem;
  color: var(--text-muted);
  text-align: center;
  background: var(--canvas-alt);
  border-radius: var(--radius);
}
.activity-table__cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
  padding-left: 0.85rem !important;
}
.activity-table__cell--mute {
  font-weight: 500;
  color: var(--text-muted);
}

.activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.activity-list__row {
  padding: 0.6rem 0;
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 0.6rem;
  font-size: 0.88rem;
}
.activity-list__row + .activity-list__row { border-top: 1px solid var(--line); }
.activity-list__title {
  grid-column: 1;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}
.activity-list__title:hover { color: var(--navy); }
.activity-list__meta {
  grid-column: 1;
  margin: 0.05rem 0 0;
  font-size: 0.8rem;
  color: var(--text-muted);
}
.activity-list__sub {
  grid-column: 1 / -1;
  margin: 0.2rem 0 0;
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.4;
}
.activity-list__when {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  font-size: 0.74rem;
  color: var(--text-soft);
  font-family: var(--font-display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.analytics-footer {
  margin: 2rem 0 0;
  font-size: 0.82rem;
  color: var(--text-soft);
  text-align: center;
}

@media (max-width: 540px) {
  .kpi-card { padding: 0.95rem 1rem; }
  .kpi-card__value { font-size: 1.85rem; }
}

/* ---------- Mobile tap behavior ----------
   touch-action: manipulation kills iOS's 300ms double-tap-to-zoom on
   interactive elements so rapid chip/button tapping doesn't zoom the
   viewport. Pinch-zoom (two-finger) still works for accessibility. */
button,
a,
.coatings-chip,
.btn,
.md-btn,
.note-nav,
.fmt-btn,
.tag-chip,
input[type="submit"],
input[type="button"],
[role="button"] {
  touch-action: manipulation;
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  html { scroll-behavior: auto; }
}

/* ── Constrained multi-select: the process picker ─────────────────────────
   Replaces the old free-text "type the process names" boxes. A grid of
   tappable checkboxes drawn from real process rows, so an editor picks from
   what exists instead of guessing a string that has to name-match exactly. */
.admin-check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14.5rem), 1fr));
  gap: 0.5rem;
  margin-top: 0.4rem;
}
.admin-check {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;                       /* let long labels ellipsize, never overflow */
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--canvas);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.admin-check:hover { border-color: var(--navy-light); }
.admin-check:focus-within { border-color: var(--navy); box-shadow: 0 0 0 3px rgba(35, 64, 102, 0.15); }
.admin-check input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1.05rem; height: 1.05rem;
  accent-color: var(--navy);
}
.admin-check__body { display: flex; flex-direction: column; gap: 0.08rem; min-width: 0; }
.admin-check__name { font-weight: 500; font-size: 0.92rem; color: var(--text); }
.admin-check__sub {
  font-size: 0.76rem; color: var(--text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Checked reads at a glance — filled navy tint + solid border. */
.admin-check:has(input:checked) { border-color: var(--navy); background: rgba(35, 64, 102, 0.06); }
/* A preserved value with no matching process row: dashed + amber sub-label so
   the editor sees it's an orphan they can uncheck to clean up. */
.admin-check--extra { border-style: dashed; }
.admin-check--extra .admin-check__sub { color: #8a6206; }
.admin-picker-empty { font-size: 0.88rem; color: var(--text-soft); margin: 0.4rem 0 0; }

/* ── Focal editor: live crop previews ────────────────────────────────────
   Two small strips under the focal photo showing how the chosen point
   survives the two real-world crops (wide page-top banner ≈21:9, content
   card ≈4:3). admin-images.js binds their background-position to the focal
   dot, so every click answers "what will this do?" instead of a blind save.
   Fixed height + aspect-ratio derives each strip's width, keeping both
   thumbnail-sized regardless of modal width. */
.image-editor-crops {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-top: var(--space-sm);
}
.image-editor-crop-row {
  display: flex;
  flex-wrap: wrap;                    /* card strip drops below on the narrowest phones */
  gap: var(--space-sm);
  align-items: flex-end;
}
.image-editor-crop {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}
.image-editor-crop-box {
  height: 72px;
  max-width: 100%;
  background-size: cover;
  background-position: 50% 50%;       /* JS overwrites with the live focal point */
  background-color: var(--canvas-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.image-editor-crop-box--wide { aspect-ratio: 21 / 9; }
.image-editor-crop-box--card { aspect-ratio: 4 / 3; }
.image-editor-crop-caption {
  font-size: 0.72rem;
  color: var(--text-muted);
  font-family: var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
/* "Edit · crop" + "Delete" can outgrow the narrowest library cards when
   side-by-side; let the pair stack instead of clipping off the card. */
.image-card-actions { flex-wrap: wrap; }

/* ---------- Phone tier: hero CTAs stack full-width ----------
   Moved out of the ≤899.98px (mobile-nav) tier 2026-08-27: on a
   744–899px tablet or a landscape phone, two stacked 100%-wide buttons
   read as billboards (Mark's iPad screenshot, launch morning). Phones
   keep the stack; everything wider gets the wrapping row. Lives at the
   end of the sheet on purpose — same specificity, later wins. */
@media (max-width: 599.98px) {
  .hero__ctas { flex-direction: column; align-items: stretch; }
  .hero__ctas .btn { width: 100%; }
}
