/* Layout primitives that replace the source CMS's client-side runtime.
 *
 * The original upgrades <column-set>, <gallery-justify>, <gallery-grid> and
 * <media-item> in the browser. The build resolves them to plain elements
 * carrying the authored numbers as custom properties, so everything below is
 * pure CSS -- no layout depends on script, and nothing here is recognizable
 * as any off-the-shelf framework.
 */

/* ---------------------------------------------------------------- reset */

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

html {
  --mobile-scale: 1.25;
  --mobile-padding-offset: 0.5;
  --fs: 2vw;
  --pad: 1rem;
  /* The original sets --vh in px from script and the authored stylesheets
   * use it for `min-height`. dvh is the correct static equivalent; site.js
   * refines it to an exact pixel value to match the original byte for byte. */
  --vh: 100dvh;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: #fff;
  color: #000;
  font-family: -apple-system, system-ui, Inter, "Segoe UI", Roboto, Oxygen,
    Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
  font-size: 14.5px;
  line-height: 1.25;
  text-rendering: optimizeLegibility;
}

* { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

img, video, svg { display: block; max-width: 100%; height: auto; }
p, span { cursor: default; }
a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }
::selection { color: #f00; text-decoration: none; }

figure { margin: 0; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: #fff; color: #000; padding: .6rem 1rem;
}
.skip:focus { left: 0; }

:focus-visible { outline: 2px solid #f00; outline-offset: 2px; }

/* --------------------------------------------------- page / pin structure */

/* This structure mirrors the original exactly: the authored stylesheet
 * and all 49 per-page stylesheets are written against `.view`,
 * `.view-frame`, `.view-body`, `.view-bg` and `[id="<nodeId>"]`.
 * Renaming any of them would silently drop the site's own styling. */

.content { position: relative; }

/* Geometry measured off the original: .view is a centered row
 * flex box; .view-frame and .view-body are row flex boxes too. The
 * authored stylesheets lean on this (e.g. "nav bottom" is pinned to the TOP
 * but renders at the bottom purely because its page fills the viewport
 * height and its content aligns to flex-end). */
.view {
  position: relative;
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: 100%;
  /* Viewport minimum heights are supplied by individual authored pages. */
  min-height: 0;
  /* The authored stylesheets set --blend (usually `difference`) and then
   * author link text as pure white, relying on the blend to render it black
   * on the white ground. Without honouring the blend the navigation is
   * literally invisible. */
  mix-blend-mode: var(--blend, normal);
}
.veil-body { mix-blend-mode: var(--veil-blend, normal); }
.view-frame {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: row;
  width: 100%;
  max-width: 100%;
}
.view-body {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  flex-wrap: wrap;
  width: 100%;
}
/* The single authored-content wrapper. Being the lone flex child, it takes
 * the full row and everything inside it flows as ordinary blocks. */
prose {
  display: block;
  width: 100%;
  max-width: 100%;
  flex: 0 1 auto;
}

.view-anchor { display: block; position: absolute; top: 0; height: 0; }

/* Pinned pages overlay the scrolling stack. `pointer-events` is opened only
 * only on the pins marked as accepting them, so a full-width affixed bar
 * cannot swallow clicks meant for the page beneath it. */
.view.affix {
  position: absolute; left: 0; right: 0; z-index: 50;
  min-height: var(--vh);
  align-items: stretch;
  pointer-events: none;
}
.view.affix.fixed { position: fixed; }
.view.affix-top { top: 0; }
/* A bottom pin is a normal in-flow block after the stack, not an overlay. */
.view.affix-bottom {
  position: relative; bottom: auto;
  min-height: 0; pointer-events: auto;
}
.view.affix > .view-frame { align-items: stretch; }
.view.affix a,
.view.affix button,
.view.affix .mi { pointer-events: auto; }

/* Separate desktop and mobile chrome are authored independently
 * (there is a distinct "logo mobile" page), so both ship and CSS picks. */
.view.only-desktop { display: block; }
.view.only-mobile { display: none; }
@media (max-width: 700px) {
  .view.only-desktop { display: none; }
  .view.only-mobile { display: block; }
}

.stack { position: relative; display: flex; flex-direction: column; }
.stack > .view { flex-direction: row; }

.view-bg {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.view-bg img, .view-bg video { display: block; width: 100%; height: 100%; object-fit: cover; }
.view-bg.wallpaper-contain img,
.view-bg.wallpaper-contain video { height: auto; object-fit: contain; }

/* ---------------------------------------------- column-set / column-unit */

.cs {
  display: grid;
  gap: var(--gutter, 1rem);
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: start;
}
.cs > .cu { min-width: 0; position: relative; }
.cs > .cu[style*="--span"] { grid-column: span calc(var(--span)); }

/* Stacking on narrow screens defaults to on; "false" keeps columns inline. */
@media (max-width: 700px) {
  .cs:not([data-mobile-stack="false"]) {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    gap: var(--mobile-gutter, var(--gutter, 1rem));
  }
  .cs:not([data-mobile-stack="false"]) > .cu { grid-column: auto; }
}

/* ------------------------------------------------------ gallery-justify */

/* Justified rows: each item's basis and growth are proportional to its
 * aspect ratio, so a row's items share the width in true proportion and the
 * row lands at the authored --row-height. Explicit breaks come from the
 * <i class="br"> the build emits after each authored row end. */
.gj {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gutter, 1rem);
  align-items: var(--row-align, center);
  margin: 0 auto;
}
.gj > .mi {
  flex-grow: var(--ar, 1);
  flex-shrink: 1;
  flex-basis: calc(var(--ar, 1) * var(--row-height, 50%));
  min-width: 0;
}
.gj > .br { flex: 0 0 100%; height: 0; margin: 0; }
.gj[data-row-align="top"] { align-items: flex-start; }
.gj[data-row-align="bottom"] { align-items: flex-end; }

@media (max-width: 700px) {
  .gj > .mi {
    flex-basis: calc(var(--ar, 1) * var(--mobile-row-height, var(--row-height, 90%)));
  }
}

/* --------------------------------------------------------- gallery-grid */

.gg {
  display: grid;
  gap: var(--gutter, 1rem);
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}
.gg > .mi[style*="--grid-span"] { grid-column: span calc(var(--grid-span)); }

@media (max-width: 700px) {
  .gg { grid-template-columns: repeat(var(--mobile-columns, 1), minmax(0, 1fr)); }
}

/* ------------------------------------------------------------ media-item */

.mi { position: relative; display: inline-flex; flex-direction: column; vertical-align: bottom; width: 100%; }
.mi .mi-media { width: 100%; height: auto; }

/* Saved freeform attributes remain archived but have no layout effect in
   the grid and justified galleries used by this site. */

.mi.zoomable .mi-media { cursor: zoom-in; }
.mi[data-zoom="off"] .mi-media { cursor: default; }
.mi.linked .mi-media { cursor: pointer; }

.mi figcaption,
.mi .caption {
  margin-top: .5rem;
}

/* ---------------------------------------------------------------- text */

.caption { font-size: calc(1em * var(--font-scale, 1)); }
.divider { border: 0; border-top: 1px solid currentColor; margin: 1.5rem 0; opacity: .4; }
.title { font-family: var(--f-times-cond); }
.arial-black { font-family: "Arial Black", Arial, sans-serif; font-weight: 900; }
.helvetica-neue-condensed-bold {
  font-family: var(--f-franklin); font-weight: 700;
}
.unica { font-family: var(--f-unica); }
.times-condensed { font-family: var(--f-times-cond); }
.caslon-l { font-family: var(--f-williams-caslon); }
.gt-america-mono { font-family: var(--f-mono); }
.h3 { font-weight: 400; margin: 0; }
.flinks:hover { text-decoration: underline; }

/* --------------------------------------------------------------- marquee */

.marquee { overflow: hidden; width: 100%; }
.marquee-inner {
  display: inline-flex; gap: 2rem; white-space: nowrap;
  will-change: transform;
  animation: marquee var(--marquee-duration, 24s) linear infinite;
}
.marquee:hover .marquee-inner { animation-play-state: paused; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* -------------------------------------------------------------- spinning */

.spinning { animation: spin 12s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------- scroll-transition */

/* Authored as uses="scroll-transition".
 *
 * Content is NOT hidden by default here, deliberately. The authored
 * stylesheet sets `span[data-fx="scroll-transition"] { opacity: 1 }`, i.e. the
 * studio turned the hide off, and the live site renders these letters
 * visible. Hiding them first made "SEATTLE USA" read "SE TTLE US" until the
 * observer fired. Script adds `.in` so the transition still has something to
 * hang off, but the resting state is visible -- which is also the correct
 * behavior with no JS and for reduced-motion readers. */
[data-fx="scroll-transition"] {
  transition: opacity .4s cubic-bezier(0, -0.01, .12, 1) .1s,
              transform .4s cubic-bezier(0, -0.01, .12, 1) .1s;
  opacity: 1;
}

/* ------------------------------------------------------------- lightbox */

.lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .94);
  padding: 2rem;
}
.lightbox[hidden] { display: none; }
.lightbox-stage { max-width: 100%; max-height: 100%; }
.lightbox-stage img, .lightbox-stage video {
  max-width: 100%; max-height: 88vh; width: auto; height: auto;
  cursor: zoom-out;
}
.lightbox-close {
  position: absolute; top: 1rem; right: 1.25rem;
  background: none; border: 0; color: #fff;
  font-size: 2rem; line-height: 1; cursor: pointer;
}

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

.footer { text-align: center; }
.footer-iii { display: inline-block; }

/* ------------------------------------------------------- accessibility */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-uses="scroll-transition"] { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------- mobile */

@media (max-width: 700px) {
  html { --fs: calc(2vw * var(--mobile-scale)); --pad: 1rem; }
  .chrome-logo img { width: 76px; }
}

/* Measured Cargo runtime geometry. Freeform attributes are inert outside
   a freeform gallery; they are saved editor values, not CSS scale factors. */
html { font-size: var(--base-size, 10px); }
html.narrow { font-size: calc(var(--base-size, 10px) * var(--mobile-scale, 1.25)); }
.view { min-height: 0; }
.view-frame { flex-grow: 1; }
.view-body { height: 100%; }
.view.affix { min-height: 0; }
.view.only-desktop { display: flex; }
.mi[style] { left: auto; top: auto; transform: none; }
.mi { min-width: 0; max-width: 100%; }
.cs { display: flex; align-items: stretch; --column-gap: var(--gutter, 1rem); gap: var(--column-gap); }
.cs > .cu { flex: var(--span, 1) 1 0; min-width: 0; }
.gg { grid-template-columns: repeat(var(--columns, 3), minmax(0, 1fr)); align-items: center; }
.gg > .br { display: none; }
.gj { display: block; }
.gj > .br { display: none; }
.gj-row { display: flex; justify-content: center; align-items: center; gap: var(--gutter, 1rem); margin-bottom: var(--gutter, 1rem); }
.gj-row > .mi { flex: none; }
.gj-row:last-child { margin-bottom: 0; }
@media (max-width: 714px) {
  .view.only-desktop { display: none; }
  .view.only-mobile { display: flex; }
  .cs:not([data-mobile-stack="false"]) { flex-direction: column; }
  .gg { grid-template-columns: repeat(var(--mobile-columns, var(--columns, 3)), minmax(0, 1fr)); gap: calc(var(--mobile-gutter, var(--gutter, 1rem)) * var(--mobile-padding-offset, .5)); }
  .gg > .mi[style*="--grid-span"] { grid-column: span var(--grid-span); }
  .gj-row { gap: var(--mobile-gutter, var(--gutter, 1rem)); margin-bottom: var(--mobile-gutter, var(--gutter, 1rem)); }
}
prose { position: relative; }

.gg { align-items: start; }
/* The authored quick view has a transparent backdrop and hidden mouse UI. */
.lightbox { background: transparent; padding: 10px; }
.lightbox-stage img, .lightbox-stage video { max-height: calc(100dvh - 20px); }
.lightbox-close { opacity: 0; color: #000; background: #fff; }
.lightbox-close:focus-visible { opacity: 1; }
@media (max-width: 714px) {
  .cs:not([data-mobile-hide-empty="false"]) > .cu:empty { display: none; }
}
/* Authored rotating circles and ticker tracks extend beyond the viewport. */
body { overflow-x: clip; }
.mi[style*="--scale:"] { width: var(--scale); }
@media (max-width: 714px) {
  .gj-row { gap: calc(var(--mobile-gutter, var(--gutter, 1rem)) * .5); margin-bottom: calc(var(--mobile-gutter, var(--gutter, 1rem)) * .5); }
}
body { position: relative; display: flex; flex-direction: column; }
.content { display: flex; flex-direction: column; }
prose { contain: layout; }
prose, prose * { font-size: calc(var(--font-scale, 1) * var(--font-size, 16px)); }
.view-body { isolation: isolate; }

.cs > .cu { flex-basis: calc((100% + var(--column-gap)) * var(--span, 1) / var(--total-span, 1) - var(--column-gap)); flex-grow: 0; }
@media (max-width: 714px) {
  .cs { --column-gap: calc(var(--mobile-gutter, var(--gutter, 1rem)) * .5); }
  .cs:not([data-mobile-stack="false"]) { gap: var(--column-gap); }
  .cs:not([data-mobile-stack="false"]) > .cu { flex-basis: auto; }
}

.cs + *, .gg + *, .gj + *, .mi + * { --gutter-expand: 1; }
.cu > :first-child { --gutter-expand: 0; }
.cs { margin-top: calc(var(--gutter-expand, 0) * var(--column-gap)); }
.gg, .gj { margin-top: calc(var(--gutter-expand, 0) * var(--gutter, 1rem)); }
@media (max-width: 714px) {
  .gg, .gj { margin-top: calc(var(--gutter-expand, 0) * var(--mobile-gutter, var(--gutter, 1rem)) * .5); }
}
