/* =============================================================================
   Masthead, roadmap, directory, footer.
   ========================================================================== */

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

.masthead {
  padding-top: clamp(var(--sp-8), 4.5vw, var(--sp-12));
  text-align: center;
}

/* Deco rule with a lit centre star. Separates the masthead from the loop
   without adding another line of text to read. The box is taller than the rule
   so the star is comfortable to hover. */
/* The rule is the element's own background rather than a `::before`, which frees
   that pseudo for the shared flare in base.css — the ornament shines exactly
   like a waypoint. */
.divider {
  position: relative;
  width: min(78%, 470px);
  height: 22px;
  margin: clamp(var(--sp-6), 4vw, var(--sp-10)) auto 0;
  --flare: 42px;
  background: linear-gradient(90deg, transparent, var(--brass-deep) 16%, var(--brass-deep) 84%, transparent)
    center / 100% 1px no-repeat;
}

.divider::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 14px;
  transform: translate(-50%, -50%);
  background: var(--brass);
  clip-path: var(--star);
  transition:
    background var(--dur) var(--ease),
    transform var(--dur) var(--ease-deco),
    filter var(--dur) var(--ease);
}

/* The wordmark is the brand asset, so the display face steps aside here and
   picks the page back up at the section headings. */
.masthead__wordmark {
  position: relative;
  display: inline-block;
  margin: 0;
  font-size: 0;
  line-height: 0;
}

.masthead__wordmark:focus {
  outline: none;
}

.masthead__wordmark img {
  display: block;
  width: min(86vw, 620px);
  height: auto;
  /* Tint first, then the rift-violet bloom off the edges of the letterforms. */
  filter: var(--wordmark-tint) drop-shadow(0 0 14px rgba(150, 90, 255, 0.55))
    drop-shadow(0 0 46px rgba(111, 59, 238, 0.35)) drop-shadow(0 6px 20px rgba(0, 0, 0, 0.6));
}

/* A specular sweep, masked to the wordmark's own alpha so the light travels
   across the letters instead of a rectangle over them. */
.masthead__shine {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  background: linear-gradient(
    100deg,
    transparent 42%,
    rgba(214, 178, 255, 0.35) 47%,
    rgba(250, 240, 255, 0.9) 50%,
    rgba(214, 178, 255, 0.35) 53%,
    transparent 58%
  );
  background-size: 320% 100%;
  background-repeat: no-repeat;
  background-position: -70% 0;
  -webkit-mask-image: url('../assets/img/logo-wordmark-1120.png');
  mask-image: url('../assets/img/logo-wordmark-1120.png');
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: wordmark-shine 7.5s var(--ease) infinite;
}

/* Sweeps in the first third, then rests — a glint, not a strobe. */
@keyframes wordmark-shine {
  0% {
    background-position: -70% 0;
  }
  32%,
  100% {
    background-position: 170% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .masthead__shine {
    display: none;
  }
}

.masthead__tagline {
  margin: var(--sp-6) auto 0;
  max-width: 52ch;
  font-size: var(--fs-lead);
  font-weight: 300;
  color: var(--muted);
  text-wrap: balance;
}

/* Hero section label sitting above the loop. The band already supplies the
   space above it, so this adds none of its own. */
.rift-label {
  text-align: center;
}

.rift-label h2 {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.15rem, 2.4vw, 1.6rem);
  text-transform: uppercase;
  letter-spacing: 0.34em;
  color: var(--parchment);
}

.rift-label p {
  margin-top: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--muted); /* a deck, like every other section deck — not a caption */
}

/* -------------------------------------------------------------- roadmap --- */

.roadmap {
  margin-top: var(--sp-8);
}

/* --- the chart ----------------------------------------------------------- */

.chart {
  --lane-label: 168px;
  border: 1px solid rgba(107, 87, 48, 0.4);
  background: rgba(9, 11, 26, 0.5);
  /* Backstop: a tooltip is anchored to stay inside the rail, but nothing here
     is ever allowed to widen the page. */
  overflow: hidden;
}

/* Two stacked header rows: the year spanning its quarters, quarters beneath.
   Every cell is bounded to its own band, so nothing can spill past the rail
   and force the whole chart to scroll. */
.chart__head {
  border-bottom: 1px solid rgba(107, 87, 48, 0.4);
  background: rgba(5, 6, 15, 0.4);
}

.chart__row {
  position: relative;
  height: 1.6rem;
  margin-left: var(--lane-label);
}

.chart__row--years {
  height: 1.5rem;
  border-bottom: 1px solid rgba(107, 87, 48, 0.2);
}

.chart__row--quarters {
  height: 1.4rem;
  border-bottom: 1px solid rgba(107, 87, 48, 0.14);
}

.chart__row--months {
  height: 1.35rem;
}

.chart__year,
.chart__quarter,
.chart__month {
  position: absolute;
  top: 0;
  left: var(--at);
  width: var(--w);
  height: 100%;
  display: grid;
  place-items: center;
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.16em;
  overflow: hidden;
  white-space: nowrap;
}

.chart__year {
  color: var(--brass);
  border-left: 1px solid rgba(107, 87, 48, 0.4);
}

.chart__quarter {
  color: var(--muted);
  border-left: 1px solid rgba(107, 87, 48, 0.22);
}

.chart__month {
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  color: var(--faint);
  border-left: 1px solid rgba(107, 87, 48, 0.1);
}

/* The row never leaves; it says less. Three letters where they fit, one where
   they do not, and a bare division when even that would collide — the months
   are what make a quarter mean anything, so the scale keeps them. `data-months`
   is set from the measured band width in scripts/roadmap.js. */
.chart[data-months='short'] .chart__month::before {
  content: attr(data-initial);
}

.chart[data-months='short'] .chart__month-name,
.chart[data-months='tick'] .chart__month-name {
  display: none;
}

.chart[data-months='tick'] .chart__row--months {
  height: 0.55rem;
}

/* Draggable in time. `pan-y` keeps a vertical swipe scrolling the page while
   the horizontal axis belongs to the chart. */
.chart__body {
  position: relative;
  cursor: grab;
  touch-action: pan-y;
}

.is-panning .chart__body {
  cursor: grabbing;
}

.chart__body:focus-visible {
  outline: 1px solid var(--brass);
  outline-offset: -1px;
}

/* Quarter grid drawn as absolutely positioned hairlines behind the lanes. It is
   inset by the label column so its percentages share the lanes' coordinates. */
.roadmap__grid {
  position: absolute;
  inset: 0 0 0 var(--lane-label);
  pointer-events: none;
}

.roadmap__gridline {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--at);
  width: 1px;
  background: rgba(107, 87, 48, 0.16);
}

.roadmap__gridline[data-year-start='true'] {
  background: rgba(107, 87, 48, 0.42);
}

/* "Now" — the only thing on the chart that moves on its own, once a day. */
.roadmap__now {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--at);
  width: 1px;
  background: linear-gradient(180deg, var(--magenta), rgba(240, 79, 212, 0.12));
  pointer-events: none;
}

.roadmap__now::after {
  content: 'Now';
  position: absolute;
  top: 2px;
  left: 5px;
  font-family: var(--data);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #ffb9ef;
}

.lane {
  display: grid;
  grid-template-columns: var(--lane-label) 1fr;
  align-items: center;
  min-height: 3rem;
  border-bottom: 1px solid rgba(107, 87, 48, 0.16);
  position: relative;
}

.lane:last-child {
  border-bottom: 0;
}

.lane__label {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: var(--sp-2) var(--sp-4);
  text-align: right;
  font-family: var(--data);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  border-right: 1px solid rgba(107, 87, 48, 0.4);
  transition: color var(--dur) var(--ease);
}

.lane__label:hover,
.lane__label:focus-visible {
  color: var(--brass-bright);
}

.lane__rail {
  position: relative;
  height: 100%;
  /* Horizontal clip only. A marker on the window's edge is cut at the rail
     rather than allowed to paint over the label column, while `overflow:
     hidden` would take the tooltips with it — they hang above and below. */
  clip-path: inset(-200px 0);
}

/* The span between first and last dated milestone. */
.lane__span {
  position: absolute;
  top: 50%;
  left: var(--from);
  width: var(--width);
  height: 1px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, var(--brass-deep), rgba(111, 59, 238, 0.5));
}

/* The marker box stays axis-aligned; only ::before carries the star, so the
   tooltip on ::after is not dragged around with it. */
/* A button, so a click opens the initiative's record and its full milestone
   list. Kept out of the tab order — the same milestones are listed as text
   below, so this is a pointer affordance and nothing is lost without it. */
.lane__mark {
  position: absolute;
  top: 50%;
  left: var(--at);
  width: 18px;
  height: 18px;
  padding: 0;
  transform: translate(-50%, -50%);
  cursor: pointer;
}

/* Centred by translate so the shared shine can scale it. Both of this button's
   pseudo-elements are spoken for — the star here, the tooltip below — so the
   flare is a real child, `.lane__flare`, added in scripts/roadmap.js. */
.lane__mark {
  --flare: 34px;
}

.lane__mark::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 16px;
  transform: translate(-50%, -50%);
  background: var(--violet);
  clip-path: var(--star);
  transition:
    transform var(--dur) var(--ease-deco),
    background var(--dur) var(--ease),
    filter var(--dur) var(--ease);
}

.lane__mark[data-done='true']::before {
  background: var(--brass);
}

.lane__mark[data-approx='true']::before {
  background: #8f7bd6;
}

/* Above its neighbours while lit, so the flare and the tooltip are not cut by
   the next marker along. */
.lane__mark:hover,
.lane__mark:focus-visible {
  z-index: 3;
}

/* Tooltip: hover only, with the same content mirrored to assistive tech in a
   visually-hidden list per lane. It sits flush against the marker and stays
   pointer-reachable, satisfying WCAG 1.4.13 Hoverable. */
.lane__mark::after {
  content: attr(data-label) ' · ' attr(data-when);
  position: absolute;
  bottom: 100%;
  width: max-content;
  max-width: 15rem;
  padding: 0.4em 0.7em;
  background: var(--panel-hi);
  border: 1px solid var(--brass-deep);
  border-bottom: 4px solid transparent;
  background-clip: padding-box;
  color: var(--parchment);
  font-family: var(--data);
  font-size: 0.68rem;
  line-height: 1.35;
  letter-spacing: 0.06em;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--dur-fast) var(--ease),
    visibility 0s linear var(--dur-fast);
}

/* Anchored to whichever edge keeps it inside the rail. */
.lane__mark[data-side='middle']::after {
  left: 50%;
  transform: translateX(-50%);
}

.lane__mark[data-side='start']::after {
  left: 0;
}

.lane__mark[data-side='end']::after {
  right: 0;
}

.lane__mark:hover::after,
.lane__mark:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.roadmap__note {
  margin-top: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--faint);
  max-width: var(--measure);
}

.roadmap__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  margin-top: var(--sp-4);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

.roadmap__legend span {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.roadmap__legend i {
  width: 12px;
  height: 12px;
  background: var(--violet);
  clip-path: var(--star);
}

.roadmap__legend i.is-done {
  background: var(--brass);
}

.roadmap__legend i.is-approx {
  background: #8f7bd6;
}

.roadmap__empty {
  padding: var(--sp-8);
  text-align: center;
  border: 1px dashed rgba(107, 87, 48, 0.4);
  color: var(--muted);
  font-family: var(--data);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
}

/* --- filters ------------------------------------------------------------- */

/* A framed control block rather than a loose row of buttons: same console
   language as the directory panel, and every cell the same size. */
.filterbar {
  margin-bottom: var(--sp-8);
  border: 1px solid rgba(107, 87, 48, 0.4);
  background: rgba(9, 11, 26, 0.5);
}

.filterbar__head {
  display: flex;
  flex-wrap: wrap; /* four controls do not fit on one line at 320px */
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid rgba(107, 87, 48, 0.35);
  background: rgba(5, 6, 15, 0.5);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
}

.filterbar__title {
  color: var(--brass);
}

.filterbar__reset {
  padding: 0.45em 0.9em;
  border: 1px solid var(--brass-deep);
  color: var(--brass-bright);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  transition:
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

.filterbar__reset:hover:not(:disabled),
.filterbar__reset:focus-visible:not(:disabled) {
  border-color: var(--brass);
  background: rgba(203, 167, 91, 0.14);
}

.filterbar__reset:disabled {
  opacity: 0.35;
  cursor: default;
}

/* The fold for the project list. Its star turns like a caret, which is the one
   piece of rotation in the console bar and so reads as a state, not decoration. */
.filterbar__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0.45em 0.9em 0.45em 0.75em;
  border: 1px solid var(--brass-deep);
  background: none;
  color: var(--brass-bright);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  transition:
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.filterbar__toggle::before {
  content: '';
  width: 9px;
  height: 9px;
  background: currentColor;
  clip-path: var(--star);
  transition: transform var(--dur) var(--ease);
}

.filterbar__toggle[aria-expanded='true']::before {
  transform: rotate(45deg);
}

.filterbar__toggle:hover,
.filterbar__toggle:focus-visible {
  border-color: var(--brass);
  background: rgba(203, 167, 91, 0.14);
}

/* Folded, the bar is only its head — no bottom rule under the last thing in it. */
.filterbar__set[hidden] {
  display: none;
}

.filterbar:has(.filterbar__set[hidden]) .filterbar__head {
  border-bottom: 0;
}

.filterbar__set {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0; /* fieldset defaults to min-content, which breaks the grid */
}

/* Equal columns, so every row of checks lines up on the same left edge. */
.filterbar__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 216px), 1fr));
}

.check {
  position: relative; /* anchors the hidden input inside its own row */
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-right: 1px solid rgba(107, 87, 48, 0.18);
  border-bottom: 1px solid rgba(107, 87, 48, 0.18);
  cursor: pointer;
  color: var(--muted);
  transition:
    color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.check:hover {
  background: rgba(23, 27, 56, 0.6);
  color: var(--parchment);
}

/* The native input stays in the accessibility tree and keeps its keyboard
   behaviour; only its painting is replaced. */
.check__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.check__box {
  position: relative;
  width: 15px;
  height: 15px;
  flex: none;
  border: 1px solid var(--brass-deep);
  background: rgba(5, 6, 15, 0.6);
  transition:
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

/* The tick is the same star the timeline marks things with. */
.check__box::after {
  content: '';
  position: absolute;
  inset: 2px;
  transform: scale(0);
  background: var(--brass-bright);
  clip-path: var(--star);
  transition: transform var(--dur) var(--ease-deco);
}

.check__input:checked + .check__box {
  border-color: var(--brass);
  background: rgba(203, 167, 91, 0.12);
}

.check__input:checked + .check__box::after {
  transform: scale(1);
}

.check__input:focus-visible + .check__box {
  outline: 2px solid var(--brass-bright);
  outline-offset: 3px;
}

.check .icon {
  width: 15px;
  height: 15px;
  flex: none;
  opacity: 0.7;
  transition: opacity var(--dur) var(--ease);
}

.check__input:checked ~ .icon {
  opacity: 1;
  color: var(--brass);
}

.check__name {
  font-family: var(--data);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.3;
}

.check__input:checked ~ .check__name {
  color: var(--parchment);
}

/* --- the time window ----------------------------------------------------- */

/* Sits inside the filter head, after the Projects button, so the row reads
   left to right as one sentence. */
.range {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

/* Zoom out and zoom in, as one pair with a shared seam. The auto margin is what
   pushes this and Reset to the far end of the bar. */
.range__zoom {
  display: inline-flex;
  margin-left: auto;
}

.range__step {
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--brass-deep);
  background: rgba(5, 6, 15, 0.7);
  color: var(--brass-bright);
  font-family: var(--data);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition:
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

.range__step + .range__step {
  margin-left: -1px;
}

.range__step:hover:not(:disabled),
.range__step:focus-visible:not(:disabled) {
  border-color: var(--brass);
  background: rgba(203, 167, 91, 0.14);
  position: relative; /* the hovered edge sits over its neighbour's border */
}

.range__step:disabled {
  opacity: 0.32;
  cursor: default;
}

.range__label {
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--faint);
}

.range__select {
  appearance: none;
  padding: 0.45em 2em 0.45em 0.8em;
  border: 1px solid var(--brass-deep);
  background:
    linear-gradient(45deg, transparent 50%, var(--brass) 50%) calc(100% - 13px) calc(50% + 2px) / 5px 5px
      no-repeat,
    rgba(5, 6, 15, 0.7);
  color: var(--parchment);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease);
}

.range__select:hover,
.range__select:focus-visible {
  border-color: var(--brass);
}

.range__select option {
  background: var(--panel);
  color: var(--parchment);
}

/* --- the pan rail -------------------------------------------------------- */

/* The window drawn against the whole span: how wide the thumb is says how much
   of the roadmap the chart is holding, and where it sits says which part. */
.pan {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

.pan__step {
  width: 1.9rem;
  height: 1.9rem;
  flex: none;
  display: grid;
  place-items: center;
  border: 1px solid var(--brass-deep);
  background: rgba(5, 6, 15, 0.7);
  color: var(--brass-bright);
  font-family: var(--data);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition:
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

.pan__step:hover:not(:disabled),
.pan__step:focus-visible:not(:disabled) {
  border-color: var(--brass);
  background: rgba(203, 167, 91, 0.14);
}

.pan__step:disabled {
  opacity: 0.32;
  cursor: default;
}

.pan__track {
  position: relative;
  flex: 1;
  height: 1.9rem;
  border: 1px solid rgba(107, 87, 48, 0.35);
  background:
    repeating-linear-gradient(90deg, rgba(107, 87, 48, 0.18) 0 1px, transparent 1px 5%),
    rgba(5, 6, 15, 0.6);
  cursor: pointer;
  touch-action: none;
}

.pan__track:focus-visible {
  outline: 1px solid var(--brass);
  outline-offset: 1px;
}

.pan__thumb {
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: var(--at);
  width: var(--w);
  min-width: 12px;
  border: 1px solid var(--brass-deep);
  background: linear-gradient(180deg, rgba(111, 59, 238, 0.36), rgba(111, 59, 238, 0.16));
  box-shadow: inset 0 0 14px rgba(111, 59, 238, 0.4);
  transition:
    left var(--dur) var(--ease),
    width var(--dur) var(--ease);
}

.pan__track:hover .pan__thumb,
.pan__track:focus-visible .pan__thumb {
  border-color: var(--brass);
}

@media (prefers-reduced-motion: reduce) {
  .pan__thumb {
    transition: none;
  }
}

/* --- work without dates -------------------------------------------------- */

.loose {
  margin-top: var(--sp-10);
}

.loose__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--brass);
}

.loose__head::after {
  content: '';
  height: 1px;
  flex: 1;
  background: linear-gradient(90deg, rgba(107, 87, 48, 0.5), transparent);
}

.loose__list {
  border: 1px solid rgba(107, 87, 48, 0.28);
  background: rgba(9, 11, 26, 0.45);
}

/* The label column matches the chart's, so the two blocks read as one table
   split by whether the work has dates. */
.loose__row {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid rgba(107, 87, 48, 0.18);
}

.loose__row:last-child {
  border-bottom: 0;
}

.loose__id {
  display: grid;
  grid-template-columns: 18px 1fr;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
}

.loose__id .icon {
  width: 17px;
  height: 17px;
  color: var(--brass);
}

.loose__name {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--parchment);
  text-align: left;
  transition: color var(--dur) var(--ease);
}

.loose__name:hover,
.loose__name:focus-visible {
  color: var(--brass-bright);
}

.loose__status {
  grid-column: 2;
  font-family: var(--data);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

.loose__miles {
  display: grid;
  align-content: center;
  gap: var(--sp-2);
}

.loose__miles li {
  display: grid;
  grid-template-columns: 12px 1fr;
  align-items: start;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.45;
}

.loose__miles i {
  width: 11px;
  height: 11px;
  margin-top: 0.34rem;
  background: var(--violet);
  clip-path: var(--star);
}

.loose__miles li[data-done='true'] i {
  background: var(--brass);
}

.loose__miles li[data-done='true'] {
  color: var(--parchment);
}

@media (max-width: 820px) {
  .loose__row {
    grid-template-columns: 1fr;
    gap: var(--sp-3);
  }
}

/* Below this the rail genuinely cannot hold eight quarters, so the chart is
   allowed to scroll — and only then. */
@media (max-width: 760px) {
  .chart {
    --lane-label: 104px;
  }

  .lane__label {
    font-size: 0.64rem;
    letter-spacing: 0.04em;
    padding-inline: var(--sp-2);
  }

  .chart__quarter,
  .chart__year {
    font-size: 0.6rem;
    letter-spacing: 0.06em;
  }
}

/* ------------------------------------------------------------ directory --- */

/* One pane of glass. The whole directory sits inside a single framed console
   rather than a scatter of cards, so it reads as one instrument. */
.panel {
  position: relative;
  overflow: hidden; /* the bay grid overhangs by a hairline on purpose */
  border: 1px solid rgba(107, 87, 48, 0.45);
  background:
    linear-gradient(180deg, rgba(23, 27, 56, 0.5), rgba(9, 11, 26, 0.62)),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.012) 0 1px, transparent 1px 3px);
  box-shadow: inset 0 0 90px rgba(111, 59, 238, 0.09);
}

/* Console header strip: a label, a live count, and a run of brass ticks. */
.panel__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-5);
  border-bottom: 1px solid rgba(107, 87, 48, 0.45);
  background: rgba(5, 6, 15, 0.5);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--brass);
}

.panel__ticks {
  flex: 1;
  height: 7px;
  background-image: repeating-linear-gradient(90deg, rgba(107, 87, 48, 0.75) 0 1px, transparent 1px 9px);
  opacity: 0.6;
}

.panel__count {
  color: var(--faint);
}

/* Columns rather than a grid: the bays hold wildly different numbers of rows,
   and grid tracks would size every cell to the tallest in its row and leave a
   dead quadrant under the short ones. Columns let them pack. */
/* Six bays, so a grid rather than columns: a column flow packs them by height
   and leaves a ragged edge, while an even grid gives every bay the same box and
   the panel a straight bottom.

   Seams are borders on the bays themselves. Which bay opens a row depends on
   how many columns fit, so instead of selecting them the whole grid is pulled a
   hairline up and left: every outer border then lands under the panel's own
   frame, and only the interior seams are left visible. */
.panel__body {
  display: grid;
  grid-template-columns: 1fr;
  margin: 0 0 -1px -1px;
}

/* Six divides by two and by three, so the grid steps 1 → 2 → 3 and the panel is
   a full rectangle at every width. Auto-fit would find room for four across on a
   wide screen and leave the last row half empty. */
@media (min-width: 560px) {
  .panel__body {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 900px) {
  .panel__body {
    grid-template-columns: repeat(3, 1fr);
  }
}

.bay {
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  border-bottom: 1px solid rgba(107, 87, 48, 0.22);
  border-left: 1px solid rgba(107, 87, 48, 0.22);
}

.bay__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--brass);
}

.bay__head .icon {
  width: 15px;
  height: 15px;
  flex: none;
  opacity: 0.75;
}

.bay__head::after {
  content: '';
  height: 1px;
  flex: 1;
  background: linear-gradient(90deg, rgba(107, 87, 48, 0.55), transparent);
}

.dir-link {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-2) var(--sp-2) 0;
  margin-left: -0.35rem;
  border-left: 2px solid transparent;
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

.dir-link__icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 1px solid rgba(107, 87, 48, 0.4);
  color: var(--muted);
  background: rgba(5, 6, 15, 0.5);
  transition:
    color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.dir-link__icon .icon {
  width: 16px;
  height: 16px;
}

.dir-link b {
  font-family: var(--body);
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--parchment);
  transition: color var(--dur) var(--ease);
}

.dir-link em {
  display: block;
  font-family: var(--data);
  font-size: 0.64rem;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  margin-top: 1px;
}

.dir-link__go {
  opacity: 0;
  color: var(--brass);
  transform: translateX(-4px);
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease-deco);
}

.dir-link:hover,
.dir-link:focus-visible {
  background: rgba(23, 27, 56, 0.75);
  border-left-color: var(--magenta);
}

.dir-link:hover b,
.dir-link:focus-visible b {
  color: var(--brass-bright);
}

.dir-link:hover .dir-link__icon,
.dir-link:focus-visible .dir-link__icon {
  color: var(--magenta);
  border-color: rgba(240, 79, 212, 0.5);
  box-shadow: 0 0 16px rgba(240, 79, 212, 0.25);
}

.dir-link:hover .dir-link__go,
.dir-link:focus-visible .dir-link__go {
  opacity: 1;
  transform: translateX(0);
}

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

.footer {
  padding-block: var(--sp-16) var(--sp-12);
  border-top: 1px solid rgba(107, 87, 48, 0.24);
  margin-top: var(--sp-16);
}

.footer__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));
  gap: var(--sp-8) var(--sp-4);
  text-align: center;
}

.footer__stat b {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.6rem, 3.4vw, 2.3rem);
  letter-spacing: 0.03em;
  line-height: 1;
  color: var(--brass-bright);
}

.footer__stat span {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

/* Equal outer tracks again, so the mark is centred on the page and not on
   whatever space the two bits of text leave behind. */
.footer__foot {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  gap: var(--sp-6);
  margin-top: var(--sp-16);
  font-family: var(--data);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.footer__when {
  justify-self: start;
}

.footer__site {
  justify-self: end;
  color: var(--brass);
  transition: color var(--dur) var(--ease);
}

.footer__site:hover,
.footer__site:focus-visible {
  color: var(--brass-bright);
}

/* --- the mark ------------------------------------------------------------- */

.footer__brand {
  display: grid;
  justify-items: center;
  gap: var(--sp-4);
  text-align: center;
}

.footer__copy {
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.14em;
  color: var(--faint);
  text-transform: none;
}

.footer__mark {
  position: relative;
  display: block;
  width: 220px;
  max-width: 100%;
  line-height: 0;
  transition: filter var(--dur) var(--ease);
}

.footer__mark img {
  display: block;
  width: 100%;
  height: auto;
}

.footer__mark:hover,
.footer__mark:focus-visible {
  filter: drop-shadow(0 0 14px rgba(111, 59, 238, 0.55)) drop-shadow(0 0 30px rgba(240, 79, 212, 0.3));
}

/* The specular sweep, masked to the logo's own alpha so the light runs across
   the artwork and not across a rectangle around it. Same treatment as the
   masthead wordmark, at footer scale. */
.footer__shine {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  background: linear-gradient(
    100deg,
    transparent 42%,
    rgba(214, 178, 255, 0.3) 47%,
    rgba(250, 240, 255, 0.85) 50%,
    rgba(214, 178, 255, 0.3) 53%,
    transparent 58%
  );
  background-size: 320% 100%;
  background-repeat: no-repeat;
  background-position: -70% 0;
  -webkit-mask-image: url('../assets/img/logo-water-480.png');
  mask-image: url('../assets/img/logo-water-480.png');
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: wordmark-shine 7.5s var(--ease) infinite;
}

@media (prefers-reduced-motion: reduce) {
  .footer__shine {
    display: none;
  }
}

/* Stacked, with the mark last — it is the sign-off. */
@media (max-width: 700px) {
  .footer__foot {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: var(--sp-6);
    text-align: center;
  }

  .footer__when,
  .footer__site {
    justify-self: center;
  }

  .footer__brand {
    order: 3;
  }
}

/* ------------------------------------------------------------ no script --- */

.noscript {
  margin: var(--sp-12) auto;
  padding: var(--sp-6);
  max-width: 56ch;
  border: 1px solid var(--brass-deep);
  background: rgba(16, 19, 42, 0.7);
  text-align: center;
  color: var(--muted);
}

.noscript a {
  color: var(--brass-bright);
  border-bottom: 1px solid var(--brass-deep);
}
