/* handyai.news shell: design tokens, the liquid glass material, the floating
   header, the phone tab bar, segmented controls and the footer. Every page
   that wears the site chrome loads this (home, articles, archives, FAQ).

   One rule runs through it: glass is for the navigation layer that floats
   over content (header, tab bar, docked Ask bar, popovers). Content sits on
   calm surfaces with the same rim light but no backdrop blur, so scrolling a
   long feed or streaming an answer never re-blurs anything big. */

:root {
  /* Brand palette, unchanged. */
  --primary: #E6E6DE;
  --background: #003F2E;
  --text: #E6E6DE;
  --text-secondary: #b8b8b0;
  --card-bg: #00543d;
  --shadow: rgba(0, 0, 0, 0.3);
  --brand-green-deep: #003F2E;
  --mint: #8fe3b9;
  --ink: #00281d;

  /* Content surfaces: a whisper of cream over the green, no blur. */
  --surface: rgba(230, 230, 222, 0.05);
  --surface-2: rgba(230, 230, 222, 0.085);
  --hairline: rgba(230, 230, 222, 0.1);
  --hairline-2: rgba(230, 230, 222, 0.2);

  /* Rim light: brightest at the top-left corner, a second catch at the
     bottom-right, the way light wraps a lens. Drawn as a 1px masked border. */
  --rim: linear-gradient(160deg, rgba(255, 255, 255, 0.36), rgba(255, 255, 255, 0.08) 28%, rgba(255, 255, 255, 0.02) 56%, rgba(255, 255, 255, 0.08) 80%, rgba(255, 255, 255, 0.24));
  --rim-soft: linear-gradient(160deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.05) 30%, rgba(255, 255, 255, 0.015) 60%, rgba(255, 255, 255, 0.1));

  /* Glass body: tinted green so it reads as part of the brand, not grey.
     Thick enough to hold text over a busy page; the sheen is light falling
     on a curved top surface, the shine is the light caught inside its
     edges. In Chromium the page behind also bends (see Refraction below). */
  --glass: rgba(6, 72, 53, 0.62);
  --glass-strong: rgba(4, 58, 43, 0.84);
  --glass-fx: blur(16px) saturate(2) brightness(1.05);
  --glass-sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.02) 46%, rgba(255, 255, 255, 0) 54%, rgba(143, 227, 185, 0.05));
  --glass-shine:
    inset 0 1px 1px rgba(255, 255, 255, 0.26),
    inset 0 -1px 1px rgba(255, 255, 255, 0.08),
    inset 0 0 14px rgba(255, 255, 255, 0.07),
    inset 0 -8px 16px -10px rgba(143, 227, 185, 0.16);
  --glass-drop: 0 14px 36px rgba(0, 16, 11, 0.4), 0 2px 8px rgba(0, 16, 11, 0.22);
  /* With refraction the frost can be lighter, so the bending shows. */
  --glass-fx-lens: url(#hai-lens) blur(5px) saturate(2) brightness(1.05);

  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 24px;
  --r-xl: 30px;

  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-ios: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-spring: cubic-bezier(0.3, 1.45, 0.5, 1);

  --gutter: 20px;
  --nav-h: 64px;
  --nav-top: 12px;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  /* Room the bottom chrome needs; 0 until the tab bar shows. */
  --tabbar-space: 0px;
}

/* No background on <html>: the body's colour then paints the canvas, which
   keeps body::before (the ambient light) above it rather than under it. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  -webkit-tap-highlight-color: transparent;
}

/* Ambient light behind everything. Glass needs something to bend; on a flat
   green it would just be a lighter rectangle. Static gradients on a fixed
   layer: painted once, never repainted on scroll. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(70vw 55vh at 8% -8%, rgba(143, 227, 185, 0.11), rgba(143, 227, 185, 0) 70%),
    radial-gradient(55vw 60vh at 104% 18%, rgba(0, 140, 102, 0.2), rgba(0, 140, 102, 0) 70%),
    radial-gradient(80vw 60vh at 40% 112%, rgba(0, 22, 16, 0.6), rgba(0, 22, 16, 0) 70%);
}

/* ------------------------------------------------------------ Material -- */

/* The rim: a 1px gradient border drawn by a masked pseudo-element, so it
   follows any radius and costs nothing to scroll. The host needs
   position: relative (or absolute/fixed). */
.rim::before,
.site-nav-glass::before,
.tabbar-pill::before,
.tabbar-ask::before,
.seg::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--rim);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

/* The robot hand, Handy AI's mark, as a glyph that takes the text colour.
   Sized by font-size (1em tall); one cached file behind every use. */
.hai-mark {
  display: inline-block;
  flex: none;
  height: 1em;
  aspect-ratio: 201 / 327;
  vertical-align: -0.14em;
  background-color: currentColor;
  -webkit-mask: url(/ui/hai-mark.svg) center / contain no-repeat;
          mask: url(/ui/hai-mark.svg) center / contain no-repeat;
}

/* A model maker's logo (ui/makers/<key>.svg, set per use in --maker-icon),
   drawn the same way so it takes the text colour. */
.maker-mark {
  display: inline-block;
  flex: none;
  width: 1.2em;
  height: 1.2em;
  background-color: currentColor;
  -webkit-mask: var(--maker-icon) center / contain no-repeat;
          mask: var(--maker-icon) center / contain no-repeat;
}

@media (forced-colors: active) {
  .hai-mark,
  .maker-mark { background-color: CanvasText; }
}

.glass {
  background: var(--glass-sheen), var(--glass);
  -webkit-backdrop-filter: var(--glass-fx);
          backdrop-filter: var(--glass-fx);
  box-shadow: var(--glass-shine), var(--glass-drop);
}

/* ------------------------------------------------------------- Header -- */

/* Floats a little below the top edge. Transparent while the page sits at
   the top, then the glass fades in as soon as anything scrolls under it. */
.site-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  padding: calc(var(--nav-top) + var(--safe-t)) var(--gutter) 0;
  margin-bottom: 30px;
  pointer-events: none;
}

.site-nav-bar {
  pointer-events: auto;
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 1160px;
  height: var(--nav-h);
  margin: 0 auto;
  padding: 0 12px 0 16px;
  border-radius: 24px;
}

body.article-page .site-nav-bar,
body.page-narrow .site-nav-bar { max-width: 860px; }

.site-nav-glass {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--glass-sheen), var(--glass);
  -webkit-backdrop-filter: var(--glass-fx);
          backdrop-filter: var(--glass-fx);
  box-shadow: var(--glass-shine), var(--glass-drop);
  opacity: 0;
  transition: opacity 0.35s ease;
}

html.is-scrolled .site-nav-glass { opacity: 1; }

/* Status-bar scrim for home-screen installs, where the page runs under the
   clock. Fades the content out under it instead of a hard edge. */
.nav-edge {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--safe-t) + 10px);
  z-index: 49;
  pointer-events: none;
  background: linear-gradient(to bottom, var(--background) 40%, rgba(0, 63, 46, 0));
}

.site-nav .logo-container {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: none;
  height: 100%;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  transition: opacity 0.25s ease;
}

/* The brand: the robot hand and the name in live type, so it stays crisp at
   any size. Once the header turns to glass the name folds into the hand and
   only the hand rides along. */
.brand-mark { height: 31px; }

.brand-word {
  display: inline-block;
  max-width: 9em;
  margin-left: 9px;
  overflow: hidden;
  color: var(--text);
  font: 600 24px/1.25 'Outfit', sans-serif;
  letter-spacing: -0.02em;
  white-space: nowrap;
  transition: max-width 0.5s var(--ease-ios), margin-left 0.5s var(--ease-ios), translate 0.5s var(--ease-ios), opacity 0.26s ease;
}

.brand-tld { color: var(--mint); }

html.is-scrolled .site-nav .brand-word {
  max-width: 0;
  margin-left: 0;
  opacity: 0;
  translate: -8px 0;
}

/* On a section page (Benchmarks, FAQ, the archives) the page's name takes
   the wordmark's place once the header sticks, in the same type. A news
   story shows its date there the same way (setNavDate). */
.nav-page {
  display: inline-block;
  max-width: 0;
  margin-left: 0;
  overflow: hidden;
  color: var(--text);
  font: 600 24px/1.25 'Outfit', sans-serif;
  letter-spacing: -0.02em;
  white-space: nowrap;
  opacity: 0;
  translate: 8px 0;
  transition: max-width 0.5s var(--ease-ios), margin-left 0.5s var(--ease-ios), translate 0.5s var(--ease-ios), opacity 0.2s ease;
}

.nav-page[hidden] { display: none; }

html.is-scrolled .site-nav .nav-page {
  max-width: 9em;
  margin-left: 10px;
  opacity: 1;
  translate: 0 0;
  transition: max-width 0.5s var(--ease-ios), margin-left 0.5s var(--ease-ios), translate 0.5s var(--ease-ios), opacity 0.3s ease 0.12s;
}

/* On a Model Drop the name gives way to the maker's logo: the hand, a
   hairline, then the lab that made the model. */
.nav-maker {
  display: inline-flex;
  align-items: center;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  translate: 8px 0;
  transition: max-width 0.5s var(--ease-ios), translate 0.5s var(--ease-ios), opacity 0.2s ease;
}

.nav-maker[hidden] { display: none; }

html.is-scrolled .site-nav .nav-maker {
  max-width: 56px;
  opacity: 1;
  translate: 0 0;
  transition: max-width 0.5s var(--ease-ios), translate 0.5s var(--ease-ios), opacity 0.3s ease 0.12s;
}

.nav-maker-sep {
  flex: none;
  width: 1px;
  height: 20px;
  margin: 0 12px;
  border-radius: 1px;
  background: rgba(230, 230, 222, 0.26);
}

.nav-maker-mark { display: inline-flex; }
.nav-maker .maker-mark { width: 23px; height: 23px; }

.nav-spacer { flex: 1; }

.nav-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

/* Controls that live inside the glass bar: a lighter lens, no second blur
   (glass on glass just turns to mud and costs a second backdrop pass). */
.nav-pill,
.nav-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 40px;
  border: 0;
  border-radius: 999px;
  background: rgba(230, 230, 222, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 0 0 1px rgba(230, 230, 222, 0.1);
  color: var(--text);
  font: 600 14px/1 'Outfit', sans-serif;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  -webkit-user-select: none;
          user-select: none;
  transition: background 0.2s ease, box-shadow 0.2s ease, scale 0.35s var(--ease-spring);
}

.nav-pill { padding: 0 12px 0 11px; }
.nav-icon { width: 40px; padding: 0; }

.nav-pill:hover,
.nav-icon:hover,
.nav-pill:focus-visible,
.nav-icon:focus-visible {
  background: rgba(230, 230, 222, 0.14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 0 0 1px rgba(230, 230, 222, 0.2);
  outline: none;
}

.nav-pill:active,
.nav-icon:active { scale: 0.94; }

.nav-pill svg,
.nav-icon svg { width: 18px; height: 18px; flex: none; }
.nav-pill .ask-spark { width: 15px; height: 15px; color: var(--mint); }

.nav-pill kbd {
  font: 500 11px/1 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  color: var(--text-secondary);
  padding: 4px 6px;
  margin-left: 2px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.18);
}

/* Back and share only exist on article pages. */
.nav-back,
.nav-share { display: none; }

body.article-page .nav-back { display: inline-flex; }

.nav-back { padding: 0 14px 0 9px; }
.nav-back svg { width: 18px; height: 18px; }

.nav-title {
  position: absolute;
  left: 64px;
  right: 64px;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  font: 600 15px/1.2 'Outfit', sans-serif;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.nav-text {
  font: 500 13px/1 'Outfit', sans-serif;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
  padding: 8px 8px;
  border-radius: 999px;
  /* 0.85 keeps it quieter than the nav while clearing WCAG AA (4.77:1 on
     the brand green; 0.7 fell to 3.73:1). */
  opacity: 0.85;
  display: inline-block;
  max-width: 8em;
  overflow: hidden;
  transition: opacity 0.2s ease, color 0.15s ease, max-width 0.45s var(--ease-ios), padding 0.45s var(--ease-ios), margin-left 0.45s var(--ease-ios), visibility 0s;
}

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

.nav-text:hover,
.nav-text:focus-visible {
  opacity: 1;
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* Once the header sticks it keeps only what a reader needs: the hand, Ask
   and back. Benchmarks and "For agents" stay at the top of every page and
   in the footer. */
html.is-scrolled .site-nav .nav-text {
  max-width: 0;
  margin-left: -8px;
  padding-left: 0;
  padding-right: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, max-width 0.45s var(--ease-ios), padding 0.45s var(--ease-ios), margin-left 0.45s var(--ease-ios), visibility 0s linear 0.45s;
}

/* On wider screens a story's share button joins Ask once the header
   sticks, opening a small glass menu. Phones show it all the time. */
@media (min-width: 721px) {
  body.article-page .nav-share {
    display: inline-flex;
    width: 0;
    margin-left: -8px;
    opacity: 0;
    visibility: hidden;
    overflow: hidden;
    transition: width 0.45s var(--ease-ios), margin-left 0.45s var(--ease-ios), opacity 0.25s ease, visibility 0s linear 0.45s, background 0.2s ease, box-shadow 0.2s ease, scale 0.35s var(--ease-spring);
  }
  html.is-scrolled body.article-page .nav-share {
    width: 40px;
    margin-left: 0;
    opacity: 1;
    visibility: visible;
    transition: width 0.45s var(--ease-ios), margin-left 0.45s var(--ease-ios), opacity 0.3s ease 0.1s, visibility 0s, background 0.2s ease, box-shadow 0.2s ease, scale 0.35s var(--ease-spring);
  }
}

/* A story's header centers the logo in a narrower bar, so between phone
   and full width there is only room for one text link. */
@media (min-width: 721px) and (max-width: 900px) {
  body.article-page .nav-text:not(.agent-badge) { display: none; }
}

.nav-actions { position: relative; }

.nav-share-menu {
  position: absolute;
  top: calc(100% + 14px);
  right: 0;
  z-index: 3;
  min-width: 200px;
  padding: 6px;
  display: grid;
  gap: 2px;
  border-radius: 18px;
  background: var(--glass-sheen), var(--glass-strong);
  -webkit-backdrop-filter: var(--glass-fx);
          backdrop-filter: var(--glass-fx);
  box-shadow: var(--glass-shine), var(--glass-drop);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px) scale(0.97);
  transform-origin: top right;
  transition: opacity 0.2s ease, transform 0.3s var(--ease-ios), visibility 0s linear 0.3s;
}

.nav-share-menu.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.2s ease, transform 0.35s var(--ease-spring), visibility 0s;
}

.nav-share-menu button {
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 40px;
  padding: 0 14px 0 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  font: 500 14px/1 'Outfit', sans-serif;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease;
}

.nav-share-menu button:hover,
.nav-share-menu button:focus-visible {
  background: rgba(230, 230, 222, 0.1);
  outline: none;
}

.nav-share-menu svg {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--mint);
}

/* Article pages: the brand sits in the middle of the bar, between back and
   the actions, and folds to the hand right there once the header sticks. */
body.article-page .site-nav .logo-container {
  position: absolute;
  left: 50%;
  top: 50%;
  height: auto;
  transform: translate(-50%, -50%);
}

/* Reading progress along the bottom of the bar, driven by the scroll
   position itself (no script), only where the browser supports it. */
.read-progress {
  position: absolute;
  left: 22px;
  right: 22px;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.read-progress span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, rgba(143, 227, 185, 0.5), var(--mint));
  transform-origin: 0 50%;
  transform: scaleX(0);
}

@supports (animation-timeline: scroll()) {
  html.is-scrolled body.article-page .read-progress { opacity: 1; }
  body.article-page .read-progress span {
    animation: hai-read-progress linear both;
    animation-timeline: scroll(root block);
  }
}

@keyframes hai-read-progress { to { transform: scaleX(1); } }

/* ------------------------------------------------------ Segmented lens -- */

/* A row of equal options with a glass lens that slides to the active one.
   Equal widths let the lens sit by index alone (--i), so it needs no
   measuring; the script only bumps --i and adds a brief squish. */
.seg {
  --n: 3;
  --i: 0;
  position: relative;
  isolation: isolate;
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  padding: 4px;
  border-radius: 999px;
  background: rgba(0, 30, 22, 0.32);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.22);
}

.seg::before { background: var(--rim-soft); }

.seg-lens {
  position: absolute;
  z-index: -1;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc((100% - 8px) / var(--n));
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(230, 230, 222, 0.17), rgba(230, 230, 222, 0.09));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 4px 14px rgba(0, 12, 8, 0.28);
  transform: translateX(calc(var(--i) * 100%));
  transition: transform 0.55s var(--ease-spring), scale 0.3s var(--ease-out);
}

.seg.is-shifting .seg-lens { scale: 1.08 0.88; }

.seg > a,
.seg > button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 8px 18px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-secondary);
  font: 500 15px/1.1 'Outfit', sans-serif;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-user-select: none;
          user-select: none;
  transition: color 0.25s ease;
}

.seg > a:hover,
.seg > button:hover { color: var(--text); }

.seg > .active,
.seg > .is-active,
.seg > [aria-current="page"] {
  color: var(--text);
  font-weight: 600;
}

.seg > :focus-visible {
  outline: 2px solid var(--mint);
  outline-offset: -2px;
}

/* ------------------------------------------------------------ Tab bar -- */

.tabbar { display: none; }

@media (max-width: 720px) {
  :root {
    --gutter: 10px;
    --nav-h: 56px;
    --nav-top: 8px;
    --tabbar-space: calc(86px + var(--safe-b));
  }

  body { padding-bottom: var(--tabbar-space); }

  .tabbar {
    position: fixed;
    z-index: 50;
    left: 0;
    right: 0;
    bottom: calc(12px + var(--safe-b));
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    pointer-events: none;
  }

  .tabbar > * {
    pointer-events: auto;
    transition: opacity 0.32s ease, translate 0.45s var(--ease-ios), scale 0.35s var(--ease-spring);
  }

  /* Scrolling down tucks it away for reading (it fades out where it sits);
     any scroll up brings it back. Phones get no floating Ask bar: the round
     Ask button here is the way in. The fade is on each piece of glass, not
     on the bar, since an ancestor's opacity would cut the glass off from
     the page behind it. */
  html.chrome-tucked .tabbar > *,
  html.ask-lock .tabbar > * {
    opacity: 0;
    translate: 0 10px;
    pointer-events: none;
  }

  .tabbar-pill {
    --n: 3;
    --i: 0;
    position: relative;
    isolation: isolate;
    flex: 1;
    max-width: 312px;
    height: 62px;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    padding: 5px;
    border-radius: 999px;
    background: var(--glass-sheen), var(--glass);
    -webkit-backdrop-filter: var(--glass-fx);
            backdrop-filter: var(--glass-fx);
    box-shadow: var(--glass-shine), var(--glass-drop);
  }

  .tabbar-lens {
    position: absolute;
    z-index: -1;
    top: 5px;
    bottom: 5px;
    left: 5px;
    width: calc((100% - 10px) / var(--n));
    border-radius: 999px;
    background: linear-gradient(180deg, rgba(230, 230, 222, 0.18), rgba(230, 230, 222, 0.09));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 4px 12px rgba(0, 12, 8, 0.24);
    transform: translateX(calc(var(--i) * 100%));
    transition: transform 0.55s var(--ease-spring), scale 0.3s var(--ease-out), opacity 0.32s ease;
  }

  .tabbar-pill.is-shifting .tabbar-lens { scale: 1.1 0.86; }
  .tabbar-pill.no-active .tabbar-lens { opacity: 0; }

  .tab {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    border-radius: 999px;
    color: var(--text-secondary);
    font: 600 10.5px/1 'Outfit', sans-serif;
    letter-spacing: 0.01em;
    text-decoration: none;
    -webkit-user-select: none;
            user-select: none;
    transition: color 0.25s ease, scale 0.35s var(--ease-spring), opacity 0.32s ease;
  }

  .tab svg { width: 23px; height: 23px; }
  .tab.is-active { color: var(--text); }
  .tab.is-active svg { color: var(--mint); }
  .tab:active { scale: 0.92; }
  .tab:focus-visible { outline: 2px solid var(--mint); outline-offset: -3px; }

  .tabbar-ask {
    position: relative;
    flex: none;
    width: 62px;
    height: 62px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    color: var(--mint);
    background: var(--glass-sheen), var(--glass);
    -webkit-backdrop-filter: var(--glass-fx);
            backdrop-filter: var(--glass-fx);
    box-shadow: var(--glass-shine), var(--glass-drop);
    cursor: pointer;
    transition: opacity 0.32s ease, translate 0.45s var(--ease-ios), scale 0.35s var(--ease-spring);
  }

  .tabbar-ask svg { width: 25px; height: 25px; }
  .tabbar-ask:active { scale: 0.9; }
  .tabbar-ask:focus-visible { outline: 2px solid var(--mint); outline-offset: 2px; }

  /* Header on phones: a slimmer capsule. Ask moves to the tab bar. */
  .site-nav { margin-bottom: 18px; }
  .site-nav-bar { padding: 0 8px 0 14px; border-radius: 22px; }
  .brand-mark { height: 28px; }
  .brand-word { margin-left: 8px; font-size: 21px; }
  .nav-page { font-size: 21px; }
  .nav-pill.ask-open { display: none; }
  .nav-text { font-size: 12.5px; }

  /* Article pages: back on the left, share on the right, the hand in the
     middle the whole way down. */
  body.article-page .site-nav-bar { padding: 0 8px; }
  body.article-page .nav-back { width: 40px; padding: 0; }
  body.article-page .nav-back span { display: none; }
  body.article-page .nav-share { display: inline-flex; }
  body.article-page .nav-text { display: none; }
  body.article-page .brand-mark { height: 26px; }
  body.article-page .brand-word { margin-left: 7px; font-size: 19px; }
  body.article-page .nav-page { font-size: 19px; }
  .nav-maker-sep { height: 18px; margin: 0 10px; }
  .nav-maker .maker-mark { width: 20px; height: 20px; }
}

/* Desktop and tablets keep ⌘K visible; touch-only screens don't need it. */
@media (hover: none) {
  .nav-pill kbd { display: none; }
}

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

.site-footer {
  margin-top: 72px;
  padding: 0 var(--gutter) 40px;
  color: var(--text-secondary);
  font-size: 14px;
}

.site-footer-card {
  position: relative;
  max-width: 1160px;
  margin: 0 auto;
  padding: 26px 28px;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 10px 28px;
  border-radius: var(--r-lg);
  background: var(--surface);
}

body.article-page .site-footer-card,
body.page-narrow .site-footer-card { max-width: 860px; }

/* The stacked lockup: hand above the name. */
.site-footer-brand {
  grid-row: span 2;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  color: var(--text);
  text-decoration: none;
}

.site-footer-brand .hai-mark { height: 42px; }

.site-footer-word {
  font: 600 16px/1 'Outfit', sans-serif;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.site-footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  align-items: center;
}

.site-footer-nav a {
  color: var(--text-secondary);
  text-decoration: none;
  font: 500 14.5px/1.4 'Outfit', sans-serif;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.site-footer-nav a:hover,
.site-footer-nav a:focus-visible {
  color: var(--text);
  border-bottom-color: var(--text);
  outline: none;
}

.site-footer-copy { margin: 0; font-size: 13px; opacity: 0.7; }

@media (max-width: 720px) {
  .site-footer { margin-top: 48px; padding-bottom: 24px; }
  .site-footer-card { grid-template-columns: 1fr; padding: 22px 20px; gap: 14px; }
  .site-footer-brand { grid-row: auto; flex-direction: row; justify-self: start; gap: 10px; }
  .site-footer-brand .hai-mark { height: 30px; }
  .site-footer-word { font-size: 19px; }
  .site-footer-nav { gap: 10px 18px; }
}

/* --------------------------------------------- Shared view transitions -- */

/* Opening a story morphs its picture from the card into the article hero
   while the rest of the page cross-fades (see navigateToArticle). */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.32s;
  animation-timing-function: var(--ease-out);
}

::view-transition-group(hai-hero) {
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.2, 0.9, 0.25, 1);
}

::view-transition-old(hai-hero),
::view-transition-new(hai-hero) {
  height: 100%;
  object-fit: cover;
  animation-duration: 0.36s;
}

/* ------------------------------------------------------ Loading line -- */

/* Opening a story that is still on its way: a short sweep runs along the
   reading line under the bar. It waits a beat, so fast loads show nothing. */
html.is-loading .read-progress {
  opacity: 1;
  transition: opacity 0.2s ease 0.16s;
}

html.is-loading .read-progress span,
html.is-loading body.article-page .read-progress span {
  width: 34%;
  transform: none;
  animation: hai-loading 1.05s cubic-bezier(0.45, 0, 0.25, 1) infinite;
  animation-timeline: auto;
}

@keyframes hai-loading {
  from { translate: -100% 0; }
  to { translate: 300% 0; }
}

/* ---------------------------------------------------- Picture viewer -- */

/* A story picture, full screen over a dimmed, blurred page (shell.js). */
.hai-viewer {
  position: fixed;
  inset: 0;
  z-index: 1200;
  touch-action: pinch-zoom;
  -webkit-user-select: none;
          user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.hai-viewer-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 22, 16, 0.78);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
          backdrop-filter: blur(22px) saturate(1.3);
}

.hai-viewer-img {
  position: fixed;
  max-width: none;
  margin: 0;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: 0 30px 80px rgba(0, 10, 7, 0.5);
  cursor: zoom-out;
  will-change: transform;
}

.hai-viewer-close {
  position: absolute;
  top: calc(14px + env(safe-area-inset-top, 0px));
  right: 14px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  color: var(--text, #e6e6de);
  background: var(--glass-sheen), var(--glass);
  -webkit-backdrop-filter: var(--glass-fx);
          backdrop-filter: var(--glass-fx);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 8px 22px rgba(0, 16, 11, 0.3);
  cursor: pointer;
  transition: scale 0.3s var(--ease-spring), background 0.2s ease;
}

.hai-viewer-close svg { width: 18px; height: 18px; }
.hai-viewer-close:hover { background: rgba(14, 96, 71, 0.6); }
.hai-viewer-close:active { scale: 0.92; }

.hai-viewer-close:focus-visible {
  outline: 2px solid var(--mint);
  outline-offset: 2px;
}

/* ------------------------------------------------------- Refraction -- */

/* Chromium only (shell.js adds html.lg-refract): the backdrop runs through
   a slow ripple before the frost, so the page bends as it slides under the
   glass. Chromium only bends a backdrop cleanly on an empty element, so the
   tab bar's glass moves onto a pseudo-element; the header already has its
   own empty layer. */
html.lg-refract .site-nav-glass {
  -webkit-backdrop-filter: var(--glass-fx-lens);
          backdrop-filter: var(--glass-fx-lens);
}

html.lg-refract .tabbar-pill,
html.lg-refract .tabbar-ask {
  isolation: isolate;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
}

html.lg-refract .tabbar-pill::after,
html.lg-refract .tabbar-ask::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  border-radius: inherit;
  background: var(--glass-sheen), var(--glass);
  -webkit-backdrop-filter: var(--glass-fx-lens);
          backdrop-filter: var(--glass-fx-lens);
  box-shadow: var(--glass-shine), var(--glass-drop);
  pointer-events: none;
  transition: opacity 0.32s ease;
}

/* With the glass on a pseudo-element, opacity on the pill itself would cut
   that layer off from the page, so tucking fades each layer instead. */
html.lg-refract .tabbar-pill,
html.lg-refract .tabbar-ask {
  background: none;
  box-shadow: none;
}

html.lg-refract .tabbar-pill::before,
html.lg-refract .tabbar-ask::before,
html.lg-refract .tabbar-ask svg { transition: opacity 0.32s ease; }

html.lg-refract.chrome-tucked .tabbar > *,
html.lg-refract.ask-lock .tabbar > * { opacity: 1; }

html.lg-refract.chrome-tucked .tabbar-pill > *,
html.lg-refract.chrome-tucked .tabbar-pill::before,
html.lg-refract.chrome-tucked .tabbar-pill::after,
html.lg-refract.chrome-tucked .tabbar-ask svg,
html.lg-refract.chrome-tucked .tabbar-ask::before,
html.lg-refract.chrome-tucked .tabbar-ask::after,
html.lg-refract.ask-lock .tabbar-pill > *,
html.lg-refract.ask-lock .tabbar-pill::before,
html.lg-refract.ask-lock .tabbar-pill::after,
html.lg-refract.ask-lock .tabbar-ask svg,
html.lg-refract.ask-lock .tabbar-ask::before,
html.lg-refract.ask-lock .tabbar-ask::after { opacity: 0; }

.hai-lens-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

/* -------------------------------------- Accessibility and fallbacks -- */

/* Readers who ask for less transparency, and browsers without backdrop
   blur, get the same shapes on solid fills. */
@media (prefers-reduced-transparency: reduce) {
  .site-nav-glass,
  .tabbar-pill,
  .tabbar-ask,
  .glass {
    background: #0b4a39;
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
  }
  .hai-viewer-scrim {
    background: rgba(0, 22, 16, 0.96);
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
  }
  body::before { display: none; }
}

@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .site-nav-glass,
  .tabbar-pill,
  .tabbar-ask,
  .glass { background: rgba(6, 66, 49, 0.96); }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav-glass,
  .seg-lens,
  .tabbar,
  .tabbar-lens,
  .tab,
  .tabbar-ask,
  .nav-pill,
  .nav-icon,
  .nav-title,
  .site-nav .logo-container { transition-duration: 0.01ms !important; }
  .brand-word,
  .nav-maker { transition: opacity 0.2s ease !important; }
  .seg.is-shifting .seg-lens,
  .tabbar-pill.is-shifting .tabbar-lens { scale: none; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
  html.is-loading .read-progress span,
  html.is-loading body.article-page .read-progress span {
    width: 100%;
    translate: none;
    animation: hai-loading-dim 1.4s ease-in-out infinite alternate;
  }
}

@keyframes hai-loading-dim {
  from { opacity: 0.25; }
  to { opacity: 0.8; }
}
