/* ============================================================
   glass-nav.css — liquid-glass section navigator
   A single capsule showing where you are, which docks to the top
   of the window as a global header once its home scrolls away,
   and opens a menu of the places you aren't.

   Built to Playground/LIQUID-GLASS.md on the CSS path that spec
   ships as its fallback (§9) rather than the WebGL one. §1 draws
   the line: the shader is for chrome floating over content that
   moves, and §3 requires the whole backdrop to be mirrored into a
   canvas for it to sample. Docked, this pill does float over
   moving content — but paying for a second copy of the entire
   page to bend a 200px capsule is the wrong trade. backdrop-filter
   gives the same surface for nothing.

   Values are the spec's light theme (§6), which sits the panel
   slightly grey so white pads have something to read against.
   ============================================================ */

:root {
  /* Light palette (§6). The panel sits slightly grey on purpose: a white
     pad needs something to read against, and a near-white surface gives a
     brightness lift nowhere to go. */
  --glass-fill: rgba(233, 236, 242, .62);
  --glass-fill-solid: #e9ecf2;
  --glass-fill-panel: rgba(244, 246, 250, .8);
  --glass-fill-panel-solid: #f4f6fa;
  --glass-rim: rgba(255, 255, 255, .5);
  --glass-pad: rgba(255, 255, 255, .75);
  --glass-pad-rim: rgba(255, 255, 255, .9);
  --glass-divider: rgba(26, 27, 31, .12);
  --glass-shadow: 0 8px 24px rgba(0, 0, 0, .16);
  /* One height for every piece of the header — the capsule and the round
     buttons beside it — so they line up as a set at every width. */
  --glass-h: 48px;
  --glass-shadow-panel: 0 12px 24px rgba(0, 0, 0, .16);
  --glass-label: rgba(26, 27, 31, .55);
  --glass-label-on: rgba(26, 27, 31, .95);
  --glass-focus: var(--gray-900);
}

/* Dark palette (§6), for the widget inside the viewer's panel. One preset,
   one palette — the component is the same, the surface it sits on isn't
   (§13). Here a pad is a brightness *lift* rather than a white fill, and
   the shadow works harder because there is no light ground to separate
   the capsule from. */
.viewer {
  --glass-fill: rgba(15, 15, 15, .72);
  --glass-fill-solid: #0f0f0f;
  --glass-rim: rgba(255, 255, 255, .14);
  --glass-pad: rgba(255, 255, 255, .085);
  --glass-pad-rim: rgba(255, 255, 255, .12);
  --glass-divider: rgba(255, 255, 255, .14);
  --glass-shadow: 0 8px 24px rgba(0, 0, 0, .30);
  --glass-label: rgba(255, 255, 255, .55);
  --glass-label-on: rgba(255, 255, 255, .92);
  --glass-focus: var(--text--primary);
}

/* Dark pages — the case studies, and the home page in dark mode — carry
   the dark palette, so the capsule sits into the page rather than glaring
   off it. The menu that drops from it is a "larger panel" in the spec's
   terms (§6): a warmer, more opaque fill and a deeper shadow than the
   capsule, so it reads as a raised sheet over the page. */
body.dark {
  --glass-fill: rgba(15, 15, 15, .72);
  --glass-fill-solid: #0f0f0f;
  --glass-fill-panel: rgba(38, 37, 34, .82);
  --glass-fill-panel-solid: #262522;
  --glass-shadow-panel: 0 12px 24px rgba(0, 0, 0, .4);
  --glass-rim: rgba(255, 255, 255, .14);
  --glass-pad: rgba(255, 255, 255, .085);
  --glass-pad-rim: rgba(255, 255, 255, .12);
  --glass-divider: rgba(255, 255, 255, .14);
  --glass-shadow: 0 8px 24px rgba(0, 0, 0, .30);
  --glass-label: rgba(255, 255, 255, .55);
  --glass-label-on: rgba(255, 255, 255, .92);
  --glass-focus: var(--text--primary);
}

/* ── Detail pages ─────────────────────────────────────────────
   A project page keeps the same header, with the run's arrows where the
   view switch sits on the home page, and the way out in the corner the
   resume link occupies there. The label names the section and opens
   nothing: the arrows are the navigation. */

.glass-nav__trigger[role="heading"] { cursor: default; }

/* The arrows are outline chevrons, drawn like the menu chevron and the exit
   cross: strokes, no fill. Doubled class so this outranks the filled
   view-icon rule further down. */
.works-views__btn.works-views__btn--arrow svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.glass-exit {
  display: flex;
  justify-content: center;
  align-items: center;
  flex: 0 0 var(--glass-h);
  width: var(--glass-h);
  height: var(--glass-h);
  border-radius: 100%;
  background-color: var(--glass-fill);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  box-shadow: var(--glass-shadow), inset 0 0 0 1px var(--glass-rim);
  color: var(--glass-label-on);
  text-decoration: none;
  transition: color .15s ease;
}
.glass-exit:hover { color: var(--glass-label-on); }
.glass-exit svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}
.glass-exit:focus-visible {
  outline: 2px solid var(--glass-focus);
  outline-offset: 3px;
}

@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass-exit { background-color: var(--glass-fill-solid); }
}

@media screen and (max-width: 479px) {
  .glass-exit svg { width: 16px; height: 16px; }
}

/* ── While the detail view is open ────────────────────────────
   The header is page chrome: it belongs to the page, not to any view
   inside it, so it stays exactly where it is when the detail view opens
   over the top. That is what every product doing this pattern does — the
   panel is a layer over the page with its own way out, and the navigation
   carries on above it.

   Only the capsule comes forward. The bar itself goes transparent and
   stops taking clicks, so it neither draws a band across the panel nor
   swallows the controls underneath it. */

html.viewer-open .navigation::before,
html.viewer-open .navigation::after { display: none; }
html.viewer-open .navigation {
  z-index: 2001;                /* over .viewer (2000) */
  background-color: #0000;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
  pointer-events: none;

  /* §6's dark palette — the capsule is over a dark ground now. */
  --glass-fill: rgba(15, 15, 15, .72);
  --glass-fill-solid: #0f0f0f;
  --glass-rim: rgba(255, 255, 255, .14);
  --glass-pad: rgba(255, 255, 255, .085);
  --glass-pad-rim: rgba(255, 255, 255, .12);
  --glass-divider: rgba(255, 255, 255, .14);
  --glass-shadow: 0 8px 24px rgba(0, 0, 0, .30);
  --glass-label: rgba(255, 255, 255, .55);
  --glass-label-on: rgba(255, 255, 255, .92);
  --glass-focus: var(--text--primary);
}

html.viewer-open .glass-nav { pointer-events: auto; }
html.viewer-open .logo-image { filter: brightness(0) invert(1); }

/* The link would sit over the panel, and leads away from a view the
   visitor has just opened. */
html.viewer-open .navigation-wrap { visibility: hidden; }

/* It sits in the navigation itself, between the logo and the resume link,
   so it is sticky because the header is — rather than floating over it and
   having to dodge what is already there. */
.glass-nav {
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
  position: relative;
  justify-self: center;
}

/* Two columns: the capsule in the left corner, and the one other thing
   the header carries in the right — the logo on the home page, the way out
   on a project page. The modifier is needed because .navigation-items is
   also the old single-row header's class. */
.navigation-items--center {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
}
.navigation-items--center .glass-nav { grid-column: 1; grid-row: 1; justify-self: start; }
.navigation-items--center .navigation-wrap,
.navigation-items--center .logo-link { grid-column: 2; grid-row: 1; justify-self: end; }

/* The capsule is taller than a line of nav text, so the band would grow and
   push the page down with it. Trimming the padding by the difference keeps
   the header at the height the rest of the layout is measured against. */
.navigation--center { padding-top: 17px; padding-bottom: 17px; }

/* ── The capsule ──────────────────────────────────────────── */

/* One surface holding both halves: what the section is called, and how it
   is laid out. They were two pills; a single sheet of glass says they
   belong to the same row of chrome rather than to two different things. */
.glass-nav__bar {
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  height: var(--glass-h);
  gap: 4px;
  padding: 5px;
  border-radius: 999px;
  background-color: var(--glass-fill);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  /* The rim is a shadow, not a border, so it adds no height (§6: the
     reference pill has no border at all — an edge is suggested). */
  box-shadow: var(--glass-shadow), inset 0 0 0 1px var(--glass-rim);
  /* The press squashes the whole sheet, which is the point: the bounce
     belongs to the surface being pressed (§8). */
  transform-origin: 50% 50%;
  will-change: transform;
}

@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass-nav__bar { background-color: var(--glass-fill-solid); }
  .glass-nav__menu { background-color: var(--glass-fill-solid); }
}

.glass-nav__trigger {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 5px 14px 5px 17px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--glass-label-on);
  font-family: Geist, sans-serif;
  font-size: 16px;
  line-height: 170%;
  white-space: nowrap;
  cursor: pointer;
}

/* Faint, because the two halves are related — a strong rule would read as
   two components sharing a container rather than one component. */
.glass-nav__divider {
  flex: 0 0 1px;
  align-self: stretch;
  margin: 6px 4px;
  background-color: var(--glass-divider);
}

/* Nothing to switch means nothing to divide; JS hides the two together. */
.glass-nav__divider[hidden] { display: none; }

/* The label is in the capsule's own ink: near-black on light pages,
   near-white on dark ones. */
.glass-nav__label { color: var(--glass-label-on); }

.glass-nav__chevron {
  width: 16px;
  height: 16px;
  color: var(--glass-label);
  transition: transform .2s ease;
}
.glass-nav__trigger[aria-expanded="true"] .glass-nav__chevron { transform: rotate(180deg); }

/* No menu while the detail view is in front, so no affordance for one.
   The chevron keeps its space rather than collapsing: a header that stays
   put should not shift 13px sideways as the affordance comes and goes. */
.glass-nav__trigger[aria-disabled="true"] { cursor: default; }
.glass-nav__trigger[aria-disabled="true"] .glass-nav__chevron { visibility: hidden; }

.glass-nav__trigger:focus-visible {
  outline: 2px solid var(--glass-focus);
  outline-offset: 3px;
}

/* ── The menu ─────────────────────────────────────────────────
   The same glass as the capsule and the round buttons beside it — fill,
   blur, rim and shadow — so the header reads as one material. */

.glass-nav__menu {
  position: absolute;
  top: calc(100% + 8px);
  /* Sized by its items alone — they are the same everywhere now — not by
     the capsule, which widens and narrows with the label above. */
  width: max-content;
  margin: 0;
  padding: 6px;
  border-radius: 20px;
  background-color: var(--glass-fill);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  box-shadow: var(--glass-shadow), inset 0 0 0 1px var(--glass-rim);
  transform-origin: 0 0;
}

/* Pinned to the capsule's left edge, not centred under it: the capsule
   widens and narrows with its label, and a centred menu jumped with it. */
.glass-nav__menu {
  left: 0;
  transform: none;
}

.glass-nav__menu[hidden] { display: none; }

@media (prefers-reduced-motion: no-preference) {
  .glass-nav__menu {
    animation: glass-nav-open .18s cubic-bezier(.2, .85, .3, 1.04) both;
  }
}

@keyframes glass-nav-open {
  from { opacity: 0; transform: translateY(-4px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

.glass-nav__item {
  display: block;
  width: 100%;
  padding: 8px 18px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--glass-label);
  font-family: Geist, sans-serif;
  font-size: 16px;
  line-height: 170%;
  white-space: nowrap;
  text-align: left;
  cursor: pointer;
  transition: color .15s ease, background-color .15s ease;
}

/* Two pads, as the spec gives a tab bar (§6): the section you are in
   takes the full selected lift, and the one under the pointer a lighter
   hover lift, so the two never read as the same thing. */
.glass-nav__item[aria-current="true"] {
  background-color: var(--glass-pad);
  color: var(--glass-label-on);
}
.glass-nav__item:hover,
.glass-nav__item:focus-visible {
  background-color: color-mix(in srgb, var(--glass-pad) 55%, transparent);
  color: var(--glass-label-on);
  outline: none;
}
.glass-nav__item[aria-current="true"]:hover,
.glass-nav__item[aria-current="true"]:focus-visible { background-color: var(--glass-pad); }
.glass-nav__item:focus-visible {
  box-shadow: inset 0 0 0 2px var(--glass-focus);
}

/* ── Layout switch ────────────────────────────────────────────
   Two icons in the same glass as the label. The active one takes the
   white pad the spec gives a selected state (§6); the accent stays on
   the label, where it is the site's only use of orange. */

.works-views {
  display: inline-flex;
  gap: 2px;
  padding-right: 2px;
}

.works-views__btn {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 100%;
  background: none;
  color: var(--glass-label);
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}

.works-views__btn svg { width: 18px; height: 18px; fill: currentColor; }

.works-views__btn:hover { color: var(--glass-label-on); }

/* Hover lifts the surface as well as the label in dark, where colour alone
   carries less (§6). */
.viewer .works-views__btn:hover:not([aria-pressed="true"]) {
  background-color: rgba(255, 255, 255, .045);
}

.works-views__btn[aria-pressed="true"] {
  background-color: var(--glass-pad);
  box-shadow: inset 0 0 0 1px var(--glass-pad-rim);
  color: var(--glass-label-on);
}

.works-views__btn:focus-visible {
  outline: 2px solid var(--glass-focus);
  outline-offset: 2px;
}

/* Meaningless while the Playground panel is showing — there is no list
   to lay out. */
.works-views[hidden] { display: none; }

/* ── Panels ───────────────────────────────────────────────── */

.works-panel[hidden] { display: none; }

.works-empty {
  color: var(--gray-600);
  font-family: Geist, sans-serif;
  font-size: 16px;
  line-height: 170%;
}

/* ── ≤ 479px ──────────────────────────────────────────────── */

@media screen and (max-width: 991px) {
  .navigation--center { padding-top: 12px; padding-bottom: 12px; }
}

/* One line at every width. Below 768 the capsule is the only one of the
   three that can give ground, so it tightens — smaller type, smaller icon
   buttons, less padding — rather than the logo shrinking or the link
   wrapping. Its widest state, "Selected Works" with both icons, is what
   these numbers are cut to fit. */
@media screen and (max-width: 767px) {
  :root { --glass-h: 38px; }
  .navigation--center { padding-top: 6px; padding-bottom: 6px; }
  .navigation-items--center { gap: 10px; }

  .glass-nav__bar { gap: 2px; padding: 4px; }
  .glass-nav__trigger {
    gap: 6px;
    padding: 4px 8px 4px 12px;
    font-size: 13px;
  }
  .glass-nav__chevron { width: 14px; height: 14px; }
  .glass-nav__divider { margin: 4px 2px; }
  .works-views { padding-right: 0; }
  .works-views__btn { width: 26px; height: 26px; }
  .works-views__btn svg { width: 15px; height: 15px; }
}

@media screen and (max-width: 479px) {
  /* The gutter the rest of the page uses at this width leaves the row a few
     pixels short, so the header keeps a tighter one of its own. */
  :root { --glass-h: 36px; }
  .navigation--center { padding-left: 16px; padding-right: 16px; }
  .navigation-items--center { gap: 6px; }


  .glass-nav__trigger { gap: 4px; padding: 4px 6px 4px 10px; font-size: 12px; }
  .works-views__btn { width: 24px; height: 24px; }
  .works-views__btn svg { width: 14px; height: 14px; }

  .glass-nav__item { padding: 8px 14px; font-size: 14px; }
}

/* The capsule keeps one width (js/glass-nav.js), so its trigger fills it:
   the label on the left, the chevron always at the right end. */
.glass-nav__bar > .glass-nav__trigger:only-child { flex: 1 1 auto; justify-content: space-between; }

/* ── The glass material, light and dark ─────────────────────────
   One recipe for every glass surface (the capsule, its menu, the round
   buttons, the highlights arrows), after the system's liquid glass: a thin,
   bright body you can see through, a specular line along the top edge, a
   faint shade along the bottom, a hairline edge and a soft lift. The light
   theme is a clear white glass rather than the old grey tint; the dark one
   keeps its smoked fill and gains the same highlights. */
:root {
  --glass-fill: rgba(252, 252, 253, .16);
  --glass-tint: linear-gradient(180deg, rgba(255, 255, 255, .4) 0%, rgba(255, 255, 255, .08) 100%);
  --glass-filter: blur(12px) saturate(180%);
  --glass-sheen: inset 0 1px 0 rgba(255, 255, 255, .95), inset 0 -1px 0 rgba(0, 0, 0, .05), inset 0 0 0 1px rgba(255, 255, 255, .5), 0 0 0 .5px rgba(0, 0, 0, .08);
  --glass-shadow: 0 10px 28px rgba(0, 0, 0, .10), 0 1px 3px rgba(0, 0, 0, .06);
  --glass-fill-solid: #f4f5f7;
}
.viewer,
body.dark,
html.viewer-open .navigation {
  --glass-tint: linear-gradient(180deg, rgba(255, 255, 255, .09) 0%, rgba(255, 255, 255, .02) 100%);
  --glass-filter: blur(20px) saturate(160%);
  --glass-sheen: inset 0 1px 0 rgba(255, 255, 255, .18), inset 0 -1px 0 rgba(0, 0, 0, .3), inset 0 0 0 1px rgba(255, 255, 255, .1), 0 0 0 .5px rgba(0, 0, 0, .4);
}

html :is(.glass-nav__bar, .glass-nav__menu, .glass-exit, .highlights__step) {
  background-color: var(--glass-fill);
  background-image: var(--glass-tint);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  box-shadow: var(--glass-shadow), var(--glass-sheen);
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html :is(.glass-nav__bar, .glass-nav__menu, .glass-exit, .highlights__step) { background-color: var(--glass-fill-solid); }
}

/* Gradient rim, after chriswelch.co's buttons: a 1px edge that is bright
   at two opposite corners and fades between them, drawn on its own layer
   and masked to the border so it never tints the glass body. */
/* The menu is already absolutely placed; the rest need a box for the rim. */
html :is(.glass-nav__bar, .glass-exit, .highlights__step) { position: relative; }
html :is(.glass-nav__bar, .glass-nav__menu, .glass-exit, .highlights__step)::after {
  content: "";
  position: absolute;
  inset: 0;
  padding: 1px;
  border-radius: inherit;
  background: var(--glass-edge);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
:root { --glass-edge: linear-gradient(315deg, rgba(255, 255, 255, .95), rgba(255, 255, 255, .4) 30%, rgba(160, 160, 170, .15) 70%, rgba(255, 255, 255, .95)); }
.viewer, body.dark, html.viewer-open .navigation {
  --glass-edge: linear-gradient(315deg, rgba(150, 150, 160, .5), rgba(150, 150, 160, .15) 30%, rgba(150, 150, 160, .02) 70%, rgba(150, 150, 160, .5));
  --glass-fill: rgba(15, 15, 15, .7);
  --glass-sheen: 0 0 0 0 transparent;
  --glass-tint: none;
  --glass-filter: blur(16px);
  --glass-shadow: 0 8px 24px rgba(0, 0, 0, .25);
}

/* Hover: the glass lightens, as chriswelch.co's buttons do (15 → 46 grey at
   the same 70%); the light glass takes a faint grey, the mirror of it. Round buttons only — the
   capsule's own controls have their pads. */
:root { --glass-fill-hover: rgba(226, 228, 233, .62); }
.viewer, body.dark, html.viewer-open .navigation { --glass-fill-hover: rgba(46, 46, 46, .7); }
html :is(.glass-exit, .highlights__step) { transition: background-color .2s ease, color .15s ease; }
html :is(.glass-exit, .highlights__step):hover,
html :is(.glass-exit, .highlights__step):focus-visible { background-color: var(--glass-fill-hover); }

/* The capsule's and its menu's rim, dark: about a quarter the round buttons' strength, so the
   larger edge reads as ambient rather than drawn. */
:is(.viewer, body.dark, html.viewer-open .navigation) :is(.glass-nav__bar, .glass-nav__menu) {
  --glass-edge: linear-gradient(315deg, rgba(150, 150, 160, .14), rgba(150, 150, 160, .04) 30%, rgba(150, 150, 160, 0) 70%, rgba(150, 150, 160, .14));
}
