/* ============================================================
   Link hub — the index

   The stack of eight glass cards was replaced by a numbered
   index: hairline-ruled rows, display type, no card chrome.

   Two things that were structural problems became free:

   - Hierarchy. Eight identical cards gave the $200 product and
     the client list the same weight. A numbered list has an
     implied reading order, so ordering the rows commercially
     now looks deliberate instead of arbitrary.

   - Desktop. The old column was capped at 460px and centred in
     whatever space it was given, so at 1600px it was a phone
     layout floating in dead space. Full-width rows use the
     viewport instead of ignoring it.

   The numerals are CSS counters on an <ol>, not markup. That
   keeps renumbering to a markup reorder, and keeps assistive
   tech from reading "zero one" before every link — the list
   semantics already carry the order.

   Accent: override --ac below.
   ============================================================ */

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

html,
body {
  margin: 0;
  padding: 0;
  background: var(--mw-background);
  -webkit-font-smoothing: antialiased;
  color-scheme: dark;
}

/* ---------- root ---------- */

.lh {
  --ac: var(--mw-accent);

  /* accent at 18% — the row hover wash. Static fallback; the @supports
     block upgrades it to track --ac. This MUST stay a @supports rule and
     not a plain redeclaration: custom properties accept any token sequence,
     so an unsupported color-mix() would win the cascade and var() would then
     resolve to nothing rather than falling back to the rgba. */
  --ac-wash: rgba(129, 65, 247, 0.18);

  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  /* own stacking context so .mw-bg (z-index 0) can never rise above the
     content (z-index 2) */
  isolation: isolate;
  background: var(--mw-background);
  font-family: var(--mw-font-body);
  color: var(--mw-text);
}

@supports (color: color-mix(in srgb, red 50%, transparent)) {
  .lh { --ac-wash: color-mix(in srgb, var(--ac) 18%, transparent); }
}

/* ---------- shell ---------- */

.lh__shell {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  min-height: 100svh;
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(26px, 4.5vh, 52px) clamp(18px, 5vw, 48px) clamp(22px, 3.5vh, 40px);
  display: flex;
  flex-direction: column;
}

/* ---------- masthead ---------- */

.lh__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: clamp(16px, 4vw, 40px);
  padding-bottom: clamp(20px, 3vh, 30px);
  border-bottom: 1px solid var(--mw-hairline);
}

.lh__logo {
  display: block;
  width: clamp(84px, 11vw, 118px);
  height: auto;
  flex: none;
}

/* The positioning statement is the most important text on the page, so it is
   the h1 — rather than inventing a decorative headline to carry the tag. */
.lh__tagline {
  margin: 0;
  max-width: 34ch;
  font-family: var(--mw-font-body);
  font-size: clamp(12px, 1.15vw, 14px);
  font-weight: var(--mw-weight-medium);
  line-height: 1.5;
  color: var(--mw-text-muted);
  text-align: right;
  text-wrap: pretty;
}

/* ---------- the index ---------- */

.lh__nav {
  flex: 1;
  display: flex;
  align-items: center;
}

.lh__index {
  width: 100%;
  margin: clamp(18px, 3vh, 34px) 0;
  padding: 0;
  list-style: none;
  counter-reset: mw-index;
}

.lh__item { counter-increment: mw-index; }

.lh__row {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: clamp(2.4rem, 4vw, 3.4rem) 1fr auto clamp(1rem, 1.6vw, 1.4rem);
  grid-template-areas: "num name meta arw";
  align-items: center;
  gap: clamp(10px, 1.6vw, 20px);
  /* Vertical padding was vh-based, which made rows shrink on any short
     viewport — a landscape phone or a split-screen tablet window. It is now
     tied to width like everything else, and min-height guarantees the row
     clears a comfortable touch target no matter what the padding resolves to. */
  min-height: 56px;
  padding: clamp(11px, 1.1vw, 17px) clamp(4px, 0.8vw, 10px);
  border-bottom: 1px solid var(--mw-hairline);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--mw-dur) var(--mw-ease);
}

.lh__row::before {
  content: counter(mw-index, decimal-leading-zero);
  grid-area: num;
  align-self: center;
  font-family: var(--mw-font-mono);
  font-size: clamp(10px, 0.95vw, 12px);
  letter-spacing: 1.4px;
  color: var(--mw-text-faint);
  transition: color var(--mw-dur-fast) var(--mw-ease);
}

/* The hover wash. A negative z-index child inside an isolated stacking
   context paints above the row's own background but below its content, so
   the wash can fade independently of anything else on the row. */
.lh__row::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, var(--ac-wash), transparent 70%);
  opacity: 0;
  transition: opacity var(--mw-dur) var(--mw-ease);
}

/* A pure-vw clamp sat pinned to its 16px floor until roughly 1320px, so every
   tablet rendered the wide layout at mobile type size — a shrunken desktop.
   The `rem + vw` form starts scaling immediately instead of idling at the
   floor, and it also keeps growing if the reader raises their base font size,
   which a viewport-only value ignores. */
.lh__name {
  grid-area: name;
  font-family: var(--mw-font-display);
  font-weight: var(--mw-weight-bold);
  font-size: clamp(17px, 0.75rem + 1.05vw, 27px);
  line-height: 1.12;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  transition: transform var(--mw-dur) var(--mw-ease),
              color var(--mw-dur) var(--mw-ease);
}

/* Was clamp(9px, …) — and 9px was the resolved value everywhere below about
   1060px, i.e. on every phone and tablet. Uppercase mono at 9px is not
   readable copy, and this line carries the price. Floor raised to 10px. */
.lh__meta {
  grid-area: meta;
  font-family: var(--mw-font-mono);
  font-size: clamp(10px, 0.4rem + 0.5vw, 12px);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--mw-text-faint);
  transition: color var(--mw-dur) var(--mw-ease);
}

.lh__arrow {
  grid-area: arw;
  justify-self: end;
  font-family: var(--mw-font-mono);
  font-size: clamp(11px, 1vw, 14px);
  font-style: normal;
  opacity: 0.4;
  transition: opacity var(--mw-dur-fast) var(--mw-ease),
              transform var(--mw-dur-fast) var(--mw-ease),
              color var(--mw-dur-fast) var(--mw-ease);
}

/* Focus is included alongside hover throughout, so nothing here is
   mouse-only. */
.lh__row:hover,
.lh__row:focus-visible { border-bottom-color: var(--mw-accent-line); }

.lh__row:hover::after,
.lh__row:focus-visible::after { opacity: 1; }

.lh__row:hover::before,
.lh__row:focus-visible::before { color: var(--ac); }

.lh__row:hover .lh__name,
.lh__row:focus-visible .lh__name { transform: translateX(8px); color: #fff; }

.lh__row:hover .lh__meta,
.lh__row:focus-visible .lh__meta { color: var(--mw-secondary); }

.lh__row:hover .lh__arrow,
.lh__row:focus-visible .lh__arrow {
  opacity: 1;
  transform: translateX(5px);
  color: var(--ac);
}

/* ---------- footer ---------- */

/* Centred stack at every width. column-reverse puts the social row above the
   copyright line while leaving the copyright first in the markup, which is
   the order it should be read and tabbed in. */
.lh__foot {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 18px;
  padding-top: clamp(18px, 2.6vh, 26px);
  border-top: 1px solid var(--mw-hairline);
  text-align: center;
}

.lh__copy {
  margin: 0;
  font-family: var(--mw-font-mono);
  font-size: 10px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--mw-text-faint);
}

.lh__social {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 44px, not 40 — these are the smallest hit areas on the page and they sit at
   the very bottom edge, where thumb accuracy is worst. */
.lh__icon,
.lh__email {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  border-radius: 4px;
  text-decoration: none;
  border: 1px solid var(--mw-hairline);
  color: var(--mw-text-muted);
  transition: border-color var(--mw-dur) var(--mw-ease),
              background var(--mw-dur) var(--mw-ease),
              color var(--mw-dur) var(--mw-ease);
}

.lh__icon { width: 44px; }

.lh__email {
  gap: 8px;
  padding: 0 14px;
  font-size: 12px;
  font-weight: var(--mw-weight-medium);
}

.lh__social svg {
  display: block;
  width: 17px;
  height: 17px;
  fill: currentColor;
}

.lh__email svg {
  width: 15px;
  height: 15px;
  fill: none; /* the envelope is stroked, not filled */
}

.lh__icon:hover,
.lh__email:hover,
.lh__icon:focus-visible,
.lh__email:focus-visible {
  border-color: var(--ac);
  background: var(--ac-wash);
  color: var(--mw-text);
}

/* ---------- keyboard ---------- */

.lh a:focus-visible {
  outline: 2px solid var(--ac);
  outline-offset: 3px;
}

/* The rows are full-bleed and already carry a visible focus treatment, so
   the ring only needs to clear the row rather than surround the text. */
.lh__row:focus-visible { outline-offset: -2px; }

/* ---------- tall viewports ----------
   The shell is header / nav / footer with the nav taking the slack, so on a
   portrait tablet the list centres itself inside ~500px of leftover height
   and the page reads half-empty. Letting the rows themselves take the space
   fills it without inventing content.

   vh is safe here in a way it was not on .lh__row's padding: the query only
   matches when the viewport is genuinely tall, so a landscape phone never
   sees it. */
@media (min-width: 641px) and (min-height: 800px) {
  .lh__row { min-height: clamp(56px, 7vh, 88px); }
}

/* ---------- narrow ---------- */

@media (max-width: 640px) {
  .lh__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }

  .lh__tagline {
    text-align: left;
    font-size: 13px;
    max-width: 40ch;
  }

  /* The meta line carries real information — price, duration, destination —
     so it wraps under the title rather than being dropped. */
  .lh__row {
    grid-template-columns: 2.3rem 1fr 1.1rem;
    grid-template-areas:
      "num name arw"
      "num meta arw";
    row-gap: 4px;
    align-items: start;
  }

  .lh__row::before,
  .lh__arrow { align-self: center; }

  /* No font-size override here on purpose. The clamp on .lh__name already
     floors at 17px and scales from there, so a flat value would only flatten
     the phone range back out. */

  /* .lh__foot needs no narrow override — it is a centred stack at every
     width. */
}

/* ---------- motion ---------- */

@media (prefers-reduced-motion: reduce) {
  /* Colour still communicates the hover; the movement does not need to.
     Durations are already 1ms from tokens.css — this drops the transforms
     so nothing jumps. */
  .lh__name,
  .lh__arrow { transition-property: color; }
  .lh__row:hover .lh__name,
  .lh__row:focus-visible .lh__name,
  .lh__row:hover .lh__arrow,
  .lh__row:focus-visible .lh__arrow { transform: none; }
}
