/* ==========================================================================
   Student Art Society
   Path: MITD/v5/sites/sas-home/assets/sas/css/sas.css

   One sheet for the whole site while there is one page. Page families get their
   own sheet through 'extra_css' when they need components nothing else uses --
   the way SPACE Mall does on DarkSpaceDepot -- rather than growing this file
   until a change for one page can break the front door.

   SAS is a LOUDER palette than the rest of MITD on purpose. DarkSpaceDepot is
   blue and violet and keeps its one bright colour for actions; this is a museum
   of student work, the artwork is the loudest thing on every screen, and the
   chrome is built to sit under it: near-black surfaces, cyan for structure and
   navigation, magenta and red reserved for the brand's own marks.
   ========================================================================== */

:root {
  --void:     #05060E;
  --panel:    #0A0D1A;
  --panel-2:  #121730;
  --ice:      #EAF2FF;
  --ash:      #8E97B0;
  --ash-dim:  #5B6480;

  --cyan:     #2FE4FF;
  --cyan-2:   #7BF1FF;
  --magenta:  #FF3D9E;
  --red:      #FF2D4F;
  --violet:   #8A4DFF;

  --hairline:    rgba(120, 200, 255, .20);
  --hairline-lo: rgba(120, 200, 255, .10);

  --gut:  clamp(18px, 3.4vw, 56px);
  --gap:  clamp(12px, 1.5vw, 20px);

  /* The accessibility button is position:fixed at the bottom-left, so it sits ON
     the last line of the page rather than after it. Every page ends with this
     much extra room, which also gives a little scroll past the footer instead of
     the footer being the hard bottom edge. env() adds the home-indicator strip
     on iOS and resolves to 0 everywhere else. */
  --a11y-clear: calc(clamp(58px, 7vh, 88px) + env(safe-area-inset-bottom, 0px));

  --ease: cubic-bezier(.22, .61, .36, 1);

  /* Text on artwork. A stack of wide, low-opacity shadows rather than one hard
     drop: it darkens whatever is immediately behind each letter without ever
     reading as an outline. */
  --lift:
    0 0 6px   rgba(0, 0, 0, .66),
    0 0 16px  rgba(0, 0, 0, .58),
    0 0 34px  rgba(0, 0, 0, .50),
    0 0 62px  rgba(0, 0, 0, .40),
    0 0 100px rgba(0, 0, 0, .30);
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body.sas {
  margin: 0;
  background: var(--void);
  color: var(--ice);
  font-family: Archivo, "Helvetica Neue", Arial, sans-serif;
  font-optical-sizing: auto;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p, figure, blockquote { margin: 0; }
img { display: block; max-width: 100%; }
svg { display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 2px; }

/* Inert links carry aria-disabled and no href (see sas_link_attrs). */
[aria-disabled="true"] { pointer-events: none; }

.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  padding: 12px 18px; background: var(--cyan); color: #04121A; font-weight: 700;
}
.skip:focus { left: 12px; top: 12px; }

.i { width: 20px; height: 20px; fill: none; stroke: currentColor;
     stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
/* The social marks are filled shapes. A one-pixel outline of a logo at 16px
   reads as mush, so these invert the rule rather than each getting its own. */
.i--solid { fill: currentColor; stroke: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; transition-duration: .001ms !important;
  }
}

/* ==========================================================================
   Masthead
   ========================================================================== */
.head {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: clamp(14px, 2.6vw, 40px);
  padding: 12px var(--gut);
  background: rgba(5, 6, 14, .82);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--hairline-lo);
}

.brand { flex: 0 0 auto; display: block; }
.brand__mark { width: clamp(118px, 12vw, 168px); height: auto; }
/* Only seen when sas-logo.png is not on the server. Wrong typeface, right
   words, still a link home -- which beats a masthead with a gap in it. */
.brand__fallback {
  display: block; font-size: clamp(16px, 1.8vw, 21px);
  font-weight: 800; font-stretch: 112%; letter-spacing: -.02em; line-height: 1;
  text-transform: uppercase;
}
.brand__fallback .is-accent { color: var(--cyan); }
.brand__fallback span + span { margin-left: .3em; }

.nav { margin-inline: auto; }
.nav__list { display: flex; align-items: center; gap: clamp(12px, 1.7vw, 28px); }
.nav__link {
  position: relative; display: block; padding: 10px 0;
  font-size: 11px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(234, 242, 255, .78); transition: color .25s var(--ease);
}
.nav__link::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 4px;
  height: 2px; background: var(--cyan); transition: right .3s var(--ease);
}
.nav__link:hover { color: var(--ice); }
.nav__link:hover::after { right: 0; }
.nav__link.is-current { color: var(--ice); }
.nav__link.is-current::after { right: 0; }

.head__tools { display: flex; align-items: center; gap: clamp(8px, 1vw, 14px); }
.tool { display: grid; place-items: center; width: 34px; height: 34px;
        border-radius: 50%; transition: background-color .25s var(--ease); }
.tool:hover { background: rgba(47, 228, 255, .14); }
.head__cta { padding: 11px 20px; }

.burger { display: none; place-items: center; width: 34px; height: 34px; }
.burger__bar { position: relative; width: 20px; height: 1.5px; background: currentColor; }
.burger__bar::before, .burger__bar::after {
  content: ""; position: absolute; left: 0; width: 20px; height: 1.5px;
  background: currentColor; transition: transform .3s var(--ease);
}
.burger__bar::before { top: -6px; }
.burger__bar::after  { top: 6px; }
.burger[aria-expanded="true"] .burger__bar { background: transparent; }
.burger[aria-expanded="true"] .burger__bar::before { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] .burger__bar::after  { transform: translateY(-6px) rotate(-45deg); }

/* ==========================================================================
   Buttons

   One shape through the whole site: an outlined cyan pill. The concept art has
   no filled button anywhere, and that is the right call for a museum -- the
   artwork is what should be saturated, not the furniture.
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 13px 24px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; white-space: nowrap;
  border: 1px solid var(--cyan);
  color: var(--ice);
  background: rgba(5, 10, 24, .5);
  backdrop-filter: blur(6px);
  transition: border-color .3s var(--ease), background-color .3s var(--ease),
              box-shadow .3s var(--ease), color .3s var(--ease);
}
.btn .i { width: 15px; height: 15px; color: var(--cyan); transition: transform .3s var(--ease); }
.btn:hover {
  background: rgba(47, 228, 255, .14);
  box-shadow: 0 0 26px rgba(47, 228, 255, .28);
}
.btn:hover .i { transform: translateX(4px); }

/* An inert button should read as not-yet, not as broken. */
.btn[aria-disabled="true"] { border-color: var(--hairline); color: rgba(234, 242, 255, .6); }
.btn[aria-disabled="true"] .i { color: var(--ash-dim); }

.chip {
  display: grid; place-items: center; flex: 0 0 auto;
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--cyan);
  transition: background-color .3s var(--ease), box-shadow .3s var(--ease);
}
.chip .i { width: 15px; height: 15px; color: var(--cyan); }
.chip:hover { background: rgba(47, 228, 255, .16); box-shadow: 0 0 20px rgba(47, 228, 255, .3); }
.chip[aria-disabled="true"] { border-color: var(--hairline); }
.chip[aria-disabled="true"] .i { color: var(--ash-dim); }

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative; isolation: isolate;
  display: flex; align-items: center;
  min-height: min(82svh, 760px);
  padding: clamp(36px, 6vw, 86px) var(--gut);
  overflow: hidden;
}
.hero__art {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: 60% 50%;
}
.hero.is-empty {
  background:
    radial-gradient(58% 64% at 62% 42%, rgba(138, 77, 255, .34), transparent 70%),
    radial-gradient(64% 70% at 24% 72%, rgba(255, 61, 158, .22), transparent 72%),
    linear-gradient(162deg, #0B1030, var(--void));
}
/* Copy sits on the left, so the veil is directional: heavy at the left edge,
   gone by mid-frame, with a floor so the CTA stays legible over bright floor
   reflections. */
.hero__veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to right, rgba(5, 6, 14, .94) 0%, rgba(5, 6, 14, .74) 24%,
                              rgba(5, 6, 14, .22) 50%, rgba(5, 6, 14, 0) 68%),
    linear-gradient(to top,   rgba(5, 6, 14, .78) 0%, rgba(5, 6, 14, 0) 32%);
}

.hero__copy { position: relative; z-index: 2; max-width: 520px; }

.hero__title {
  font-size: clamp(42px, 6.2vw, 88px);
  font-weight: 900; font-stretch: 108%;
  line-height: .92; letter-spacing: -.035em; text-transform: uppercase;
  text-shadow: var(--lift);
}
.hero__line { display: block; }
/* One accented word per headline. The colour is doing the emphasis, and a
   headline with two emphasised words has none. */
.hero__line.is-accent { color: var(--cyan); }

/* The painted stroke. Width is tied to the headline's own size so it stays the
   length of a word rather than the length of the column. */
.stroke {
  width: min(100%, clamp(150px, 20vw, 290px));
  height: clamp(9px, 1.1vw, 15px);
  margin-top: clamp(14px, 1.6vw, 22px);
  filter: drop-shadow(0 0 18px rgba(255, 45, 79, .45));
}
.stroke__a { stop-color: var(--red); }
.stroke__b { stop-color: var(--magenta); }
.stroke__c { stop-color: var(--magenta); stop-opacity: 0; }

/* No max-width of its own: the copy column is already 520px and that is the
   measure. It was capped at 34ch, which is about 250px -- but ch counts a "0"
   glyph and knows nothing about letter-spacing, and this text is uppercase at
   .12em. "A VIRTUAL MUSEUM FOR STUDENT ARTISTS." needs roughly 350px, so the
   cap was breaking a written line in half and leaving ARTISTS. on its own. */
.hero__lede { margin-top: clamp(18px, 2.2vw, 30px); }
.hero__lede span {
  display: block;
  font-size: clamp(11px, .95vw, 13px); font-weight: 500;
  letter-spacing: .12em; line-height: 1.95; text-transform: uppercase;
  color: rgba(234, 242, 255, .86);
  text-shadow: var(--lift);
}
.hero__ctas { display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(22px, 2.8vw, 34px); }

/* ==========================================================================
   Band frame

   Top padding only: each band opens its own gap, so bands can be added,
   removed or reordered in a content file without anything below them needing
   to know. The last one's bottom gap comes from the footer.
   ========================================================================== */
.band { padding: clamp(30px, 4.4vw, 64px) var(--gut) 0; }

/* ==========================================================================
   Scroller — native, with two added buttons

   overflow-x and snap points, not a JS carousel. It works with a trackpad, a
   touch screen and a scroll wheel before any script loads, the track is a real
   list so Tab reaches every card, and if sas.js fails the only thing lost is
   the chevrons.
   ========================================================================== */
.scroller__track {
  display: flex; gap: var(--gap);

  /* position:relative is NOT decoration here, it is the fix for a real bug.
     A static-position scroll container clips its own painting, but its layout
     overflow still propagates up to its ancestors -- so with five cards in a
     354px track the document grew to 1137px on a 390px phone. The page looked
     right until you scrolled sideways or pinched out, and then two thirds of
     the viewport was empty black beside a column of content.

     Positioning the track contains that overflow at the right place, which is
     the one fix here that changes nothing visually: overflow:hidden on an
     ancestor also stops it, but it would clip the chevrons that deliberately
     sit outside the track's edges on desktop. Measured, not assumed --
     document.scrollWidth goes 1137 -> 390 with this one line. */
  position: relative;

  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 2px;
  /* Room for the focus ring, which the scroll container would otherwise clip
     on the first and last card. */
  padding: 4px 2px 8px;
  scrollbar-width: none;
}
.scroller__track::-webkit-scrollbar { display: none; }
.scroller__track > * { scroll-snap-align: start; }

.scroller__btn {
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%;
  color: var(--cyan);
  transition: background-color .25s var(--ease), opacity .25s var(--ease);
}
.scroller__btn .i { width: 20px; height: 20px; stroke-width: 1.6; }
.scroller__btn:hover { background: rgba(47, 228, 255, .16); }
/* Set by sas.js when the track is already at that end. Dimmed rather than
   removed, so the control does not shift position mid-scroll. */
.scroller__btn.is-spent { opacity: .22; pointer-events: none; }

/* ==========================================================================
   Featured artists
   ========================================================================== */
.band--artists {
  display: grid; grid-template-columns: minmax(0, .3fr) minmax(0, 1fr);
  align-items: center; gap: clamp(18px, 2.6vw, 44px);
}

.aintro__title {
  font-size: clamp(26px, 3.1vw, 44px); font-weight: 900; font-stretch: 106%;
  line-height: .96; letter-spacing: -.03em; text-transform: uppercase;
}
.aintro__title span { display: block; }
.aintro__lede { margin-top: clamp(12px, 1.4vw, 18px); }
.aintro__lede span {
  display: block;
  font-size: clamp(11.5px, .95vw, 13px); line-height: 1.75;
  color: var(--ash);
}
.aintro .btn { margin-top: clamp(16px, 2vw, 26px); }

/* The rail is positioned so the chevrons can flank the cards, as in the concept
   art, rather than sitting up in the heading row -- the cards are the subject
   of this section, so the controls belong against them. */
.arail { position: relative; }
.arail__nav { position: absolute; inset: 0; pointer-events: none; }
.arail__nav .scroller__btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  pointer-events: auto;
}
.scroller__btn--prev { left: clamp(-34px, -2.2vw, -10px); }
.scroller__btn--next { right: clamp(-34px, -2.2vw, -10px); }

.acards { align-items: stretch; }

.acard {
  /* position: relative is what the stretched anchor resolves against -- the
     whole card is the hit target, not just the chip in its corner. */
  position: relative;
  display: flex; flex-direction: column;
  flex: 0 0 clamp(168px, 17vw, 218px);
  border: 1px solid var(--hairline-lo); border-radius: 12px;
  background: linear-gradient(168deg, rgba(26, 34, 70, .5), rgba(8, 11, 22, .82));
  overflow: hidden;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.acard:hover { border-color: var(--cyan); box-shadow: 0 0 26px rgba(47, 228, 255, .2); }
/* The ring belongs to the CARD, not to the transparent anchor lying over it.
   An outline on that anchor happens to land in the right place today and stops
   doing so the moment its box changes; :focus-within puts it on the thing the
   visitor can actually see being focused. */
.acard:focus-within { outline: 2px solid var(--cyan); outline-offset: 3px; }
.acard__go { position: absolute; inset: 0; z-index: 2; }
.acard__go:focus-visible { outline: none; }
/* The card lifts on hover wherever the pointer is on it, including over the
   arrow, because the anchor covers all of it. */
.acard:hover .chip { background: rgba(47, 228, 255, .16); box-shadow: 0 0 20px rgba(47, 228, 255, .3); }

.acard__media { display: block; }
.acard__media img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.acard.is-empty .acard__media {
  aspect-ratio: 3 / 4;
  background:
    radial-gradient(74% 60% at 40% 28%, rgba(255, 61, 158, .32), transparent 70%),
    linear-gradient(150deg, #1A1138, #070912);
}

.acard__foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px 14px; margin-top: auto;
}
.acard__who { display: block; min-width: 0; }
.acard__name {
  display: block;
  font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.acard__medium {
  display: block; margin-top: 4px;
  font-size: 10px; letter-spacing: .04em; color: var(--ash);
}
/* The arrow on a card whose destination is not confirmed. Same muted treatment
   as an inert link elsewhere, reached by a class rather than by
   [aria-disabled] because this is no longer an anchor. */
.acard .chip { flex: 0 0 auto; }
.acard .chip.is-inert { border-color: var(--hairline); }
.acard .chip.is-inert .i { color: var(--ash-dim); }
.acard:hover .chip.is-inert { background: none; box-shadow: none; }

/* ==========================================================================
   The four ways in
   ========================================================================== */
.gates {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap);
}
.gate {
  position: relative;
  display: flex; flex-direction: column;
  border: 1px solid var(--hairline-lo); border-radius: 12px;
  background: linear-gradient(168deg, rgba(26, 34, 70, .45), rgba(8, 11, 22, .8));
  overflow: hidden;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.gate:hover { border-color: var(--cyan); box-shadow: 0 0 26px rgba(47, 228, 255, .18); }

.gate__media { display: block; }
.gate__media img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.gate.is-empty .gate__media {
  aspect-ratio: 16 / 9;
  background:
    radial-gradient(70% 72% at 38% 32%, rgba(138, 77, 255, .34), transparent 70%),
    linear-gradient(145deg, #141B3C, #070912);
}

.gate__body {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 14px;
  padding: 16px 16px 18px; margin-top: auto;
}
.gate__text { display: block; min-width: 0; }
.gate__title {
  display: block;
  font-size: 14px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
}
.gate__lines { display: block; margin-top: 8px; }
.gate__line {
  display: block;
  font-size: 11.5px; line-height: 1.6; color: var(--ash);
}

/* The whole card is the target. The chip stays the thing that looks clickable
   and keeps the short accessible name, but its ::after covers the card so the
   click area is the card -- a 34px circle is a small ask on a touch screen. */
.gate__go::after { content: ""; position: absolute; inset: 0; }

/* ==========================================================================
   Emerging artists
   ========================================================================== */
.emerge {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; justify-content: space-between;
  gap: clamp(30px, 5vw, 70px);
  min-height: clamp(380px, 40vw, 560px);
  padding: clamp(28px, 4vw, 60px) clamp(22px, 3.4vw, 54px);
  border-radius: 14px; overflow: hidden;
  border: 1px solid var(--hairline-lo);
}
.emerge__art { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%;
                object-fit: cover; object-position: 50% 46%; }
.emerge.is-empty {
  background:
    radial-gradient(60% 70% at 72% 40%, rgba(47, 228, 255, .26), transparent 70%),
    radial-gradient(60% 70% at 24% 66%, rgba(255, 61, 158, .24), transparent 72%),
    linear-gradient(155deg, #0D1232, #05070F);
}
/* Dark where the words are: left for the statement, a floor across the bottom
   for the claims, and the middle of the picture left alone. */
.emerge__veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to right, rgba(5, 6, 14, .9) 0%, rgba(5, 6, 14, .6) 34%,
                              rgba(5, 6, 14, .12) 64%, rgba(5, 6, 14, 0) 100%),
    linear-gradient(to top,   rgba(5, 6, 14, .88) 0%, rgba(5, 6, 14, .4) 22%,
                              rgba(5, 6, 14, 0) 46%);
}

.emerge__copy { position: relative; z-index: 2; max-width: 30ch; }
.emerge__title {
  font-size: clamp(30px, 4.2vw, 58px); font-weight: 900; font-stretch: 106%;
  line-height: .94; letter-spacing: -.035em; text-transform: uppercase;
  text-shadow: var(--lift);
}
.emerge__title span { display: block; }
.emerge__title .is-accent { color: var(--cyan); }
.emerge__lede { margin-top: clamp(14px, 1.8vw, 22px); }
.emerge__lede span {
  display: block;
  font-size: clamp(13px, 1.15vw, 18px); font-weight: 500; line-height: 1.45;
  text-transform: uppercase; letter-spacing: .02em;
  color: rgba(234, 242, 255, .9);
  text-shadow: var(--lift);
}
.emerge__copy .btn { margin-top: clamp(18px, 2.2vw, 28px); }

.claims {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap);
}
.claim { display: flex; flex-direction: column; align-items: center; gap: 10px;
         text-align: center; }
.claim__icon { color: var(--cyan); }
.claim__icon .i { width: 28px; height: 28px; stroke-width: 1.2; }
.claim__text span {
  display: block;
  font-size: 10.5px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; line-height: 1.6;
  text-shadow: var(--lift);
}

/* ==========================================================================
   Divider
   ========================================================================== */
.divider {
  display: flex; align-items: center; gap: clamp(14px, 2vw, 28px);
  padding-top: clamp(10px, 1.4vw, 18px);
}
.divider::before, .divider::after {
  content: ""; flex: 1 1 auto; height: 1px;
  background: linear-gradient(to right, transparent, var(--hairline), transparent);
}
.divider__text {
  flex: 0 0 auto;
  font-size: 10.5px; font-weight: 700; letter-spacing: .3em; text-transform: uppercase;
  color: var(--cyan);
}

/* ==========================================================================
   Closing triptych
   ========================================================================== */
/* ONE CONTINUOUS STRIP OF ARTWORK, with the copy on a scrim over the middle of
   it -- not three panels in a row with a solid block between them.

   The right-hand render spans columns 2 AND 3, so it runs left until it meets
   the mark panel and the two pictures touch. The copy then sits in column 2 on
   top of it. Explicit grid-area on all three rather than source order, because
   two of them share a cell and only an explicit placement says which. */
.manif {
  display: grid;
  grid-template-columns: minmax(0, .58fr) minmax(0, 1.05fr) minmax(0, .88fr);
  align-items: stretch;
  border: 1px solid var(--hairline-lo); border-radius: 14px; overflow: hidden;
}
.manif__panel--mark  { grid-area: 1 / 1 / 2 / 2; }
.manif__panel--words { grid-area: 1 / 2 / 2 / 4; }
.manif__copy         { grid-area: 1 / 2 / 2 / 3; position: relative; z-index: 2; }

.manif__panel {
  position: relative; isolation: isolate;
  display: grid; place-items: center;
  min-height: clamp(260px, 26vw, 380px);
  padding: clamp(20px, 2.6vw, 38px);
}
.manif__art { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%;
               object-fit: cover; }
.manif__veil { position: absolute; inset: 0; z-index: 1; pointer-events: none;
               background: rgba(5, 6, 14, .42); }
/* The right render now runs under the copy panel as well as beside it, so its
   subject is pushed right -- otherwise cover() centres the figure behind the
   scrim and the visible part of the picture is empty sky. */
.manif__panel--words .manif__art { object-position: 74% 50%; }
.manif__panel--mark.is-empty {
  background:
    radial-gradient(70% 70% at 46% 42%, rgba(255, 61, 158, .34), transparent 70%),
    linear-gradient(150deg, #1A1038, #06070F);
}
.manif__panel--words.is-empty {
  background:
    radial-gradient(70% 70% at 56% 40%, rgba(47, 228, 255, .28), transparent 70%),
    linear-gradient(150deg, #0C1434, #06070F);
}
.manif__mark {
  position: relative; z-index: 2;
  width: min(84%, 300px); height: auto;
  filter: drop-shadow(0 0 30px rgba(0, 0, 0, .6));
}

/* A scrim, not a slab -- and a thin enough one that you can see it IS a scrim.
   The panels have met at the column boundary since the grid change, but at .97
   opacity the picture underneath was invisible, so the band still read as a
   dark block sitting between two images rather than as one image with a veil
   over part of it.

   It now opens at .9 behind the heading and falls away to .14, which puts the
   artwork plainly on screen from the moment the mark panel ends. The text is
   held by the shadow stack instead -- the same trade the hero makes, and the
   right one: a shadow darkens only what is directly behind each letter, where a
   scrim heavy enough to do the same job blanks the whole panel. */
.manif__copy {
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(24px, 3vw, 46px);
  background: linear-gradient(to right,
    rgba(5, 6, 14, .90) 0%, rgba(5, 6, 14, .80) 44%,
    rgba(5, 6, 14, .52) 78%, rgba(5, 6, 14, .14) 100%);
  backdrop-filter: blur(10px);
}
.manif__title {
  font-size: clamp(20px, 2.3vw, 32px); font-weight: 800; font-stretch: 104%;
  line-height: 1.08; letter-spacing: -.02em; text-transform: uppercase;
  text-shadow: var(--lift);
}
.manif__title span { display: block; }
/* Prose, so it flows. The source is written as lines for readability in the
   content file, but they are set inline and the browser breaks them where they
   actually fit -- a forced break inside a sentence is how a column ends up with
   one word on a line of its own the first time the panel narrows. */
.manif__lede { margin-top: clamp(12px, 1.5vw, 20px); max-width: 52ch; }
.manif__lede span {
  display: inline;
  font-size: clamp(12px, 1vw, 14px); line-height: 1.7;
  color: rgba(234, 242, 255, .88);
  text-shadow: var(--lift);
}
.manif__copy .btn { align-self: flex-start; margin-top: clamp(18px, 2.2vw, 28px); }

/* The word list hangs off the right edge of its panel, as in the concept art --
   a column of words set against the artwork rather than centred in it. */
.manif__panel--words { place-items: center end; }
.wordlist { position: relative; z-index: 2; text-align: right; display: grid; gap: 6px; }
.wordlist li {
  font-size: 10.5px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase;
  color: rgba(234, 242, 255, .88);
  text-shadow: var(--lift);
}
.wordlist__tail { color: var(--cyan); }

/* ==========================================================================
   Footer
   ========================================================================== */
.foot {
  margin-top: clamp(36px, 5vw, 76px);
  padding: clamp(22px, 2.6vw, 34px) var(--gut) var(--a11y-clear);
  border-top: 1px solid var(--hairline-lo);
}
.foot__row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: clamp(16px, 3vw, 40px);
}
.brand--foot .brand__mark { width: clamp(118px, 11vw, 150px); }

.foot__links { display: flex; flex-wrap: wrap; gap: clamp(14px, 2vw, 30px); }
.foot__links a {
  font-size: 10.5px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(234, 242, 255, .76); transition: color .25s var(--ease);
}
.foot__links a:hover { color: var(--cyan); }
.foot__links a[aria-disabled="true"] { color: var(--ash-dim); }

.foot__social { display: flex; align-items: center; gap: 10px; }
.social {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  color: rgba(234, 242, 255, .8);
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.social .i { width: 17px; height: 17px; }
.social:hover { background: rgba(47, 228, 255, .16); color: var(--cyan); }
.social[aria-disabled="true"] { color: var(--ash-dim); }

.foot__legal {
  margin-top: clamp(16px, 2vw, 26px); padding-top: 16px;
  border-top: 1px solid var(--hairline-lo);
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ash-dim);
}

/* ==========================================================================
   Responsive

   The masthead and the bands change shape at the same widths, so the page never
   reads as two layouts stapled together.
   ========================================================================== */
@media (max-width: 1180px) {
  .gates { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Two columns, two rows: the statement across the top and the two renders
     side by side beneath it. The copy stops overlapping the artwork here --
     there is no longer enough width for a scrim to sit on, and the statement is
     the point of this band while the pictures are its setting. */
  .manif { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .manif__copy         { grid-area: 1 / 1 / 2 / 3; background: var(--panel);
                         backdrop-filter: none; }
  .manif__panel--mark  { grid-area: 2 / 1 / 3 / 2; }
  .manif__panel--words { grid-area: 2 / 2 / 3 / 3; }
  .manif__panel--words .manif__art { object-position: 50% 50%; }
}

@media (max-width: 960px) {
  .band--artists { grid-template-columns: minmax(0, 1fr); }
  /* The chevrons flanked the rail while there was a column of copy beside it to
     flank it against. Full width, they would hang off the gutter, so they come
     back inside the track. */
  .scroller__btn--prev { left: 2px; }
  .scroller__btn--next { right: 2px; }
  .arail__nav .scroller__btn {
    background: rgba(5, 6, 14, .72); backdrop-filter: blur(8px);
    border: 1px solid var(--hairline);
  }
  .claims { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 22px; }
}

@media (max-width: 860px) {
  .head { flex-wrap: wrap; gap: 10px; }
  .burger { display: grid; }

  .nav {
    order: 3; flex-basis: 100%; margin-inline: 0;
    display: none; padding-top: 6px; border-top: 1px solid var(--hairline-lo);
  }
  .nav.is-open { display: block; }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__list li { border-bottom: 1px solid var(--hairline-lo); }
  .nav__list li:last-child { border-bottom: 0; }
  .nav__link { padding: 14px 0; }
  .nav__link::after { display: none; }
  .nav__link.is-current { color: var(--cyan); }

  .head__tools { margin-left: auto; }
  /* "Enter museum" is the one thing in the masthead that is not navigation, and
     at this width it is competing with the burger for the same corner. It is
     repeated at the end of the page, so it steps aside here. */
  .head__cta { display: none; }

  .hero { min-height: 0; align-items: flex-start; }
  .hero__art { object-position: 66% 42%; }
  .hero__veil {
    background:
      linear-gradient(to right, rgba(5, 6, 14, .92) 0%, rgba(5, 6, 14, .68) 58%,
                                rgba(5, 6, 14, .42) 100%),
      linear-gradient(to top,   rgba(5, 6, 14, .86) 0%, rgba(5, 6, 14, 0) 46%);
  }

  .emerge__veil {
    background:
      linear-gradient(to bottom, rgba(5, 6, 14, .78) 0%, rgba(5, 6, 14, .66) 46%,
                                 rgba(5, 6, 14, .92) 100%);
  }
  .emerge__copy { max-width: none; }

  .foot__row { justify-content: flex-start; }
  .foot__social { margin-left: auto; }
}

@media (max-width: 620px) {
  .gates { grid-template-columns: minmax(0, 1fr); }

  .manif { grid-template-columns: minmax(0, 1fr); }
  .manif__copy         { grid-area: 1 / 1 / 2 / 2; }
  .manif__panel--mark  { grid-area: 2 / 1 / 3 / 2; }
  .manif__panel--words { grid-area: 3 / 1 / 4 / 2; place-items: center; }
  .wordlist { text-align: center; }
  .claims { grid-template-columns: minmax(0, 1fr); }
  .claim { flex-direction: row; align-items: center; gap: 14px; text-align: left; }
  .acard { flex: 0 0 min(62vw, 220px); }
  .divider__text { letter-spacing: .2em; font-size: 9.5px; }

  /* The lede stops being three written lines and becomes one paragraph. At this
     width the authored breaks cannot hold -- every line would wrap anyway, and
     a forced break followed by a natural one gives the ragged two-word orphan
     this was written to avoid. Inline, the browser breaks it where it fits.
     The spans are on separate source lines, so the newline between them
     collapses to the space that makes this read as a sentence. */
  .hero__lede span { display: inline; letter-spacing: .1em; }
}

/* ==========================================================================
   Contact form

   Two columns on a laptop, one on a phone, with the form SECOND in the source
   so reading order and tab order both run: what this is, then how to say it.
   The panel sits to the right on a wide screen purely by grid placement, which
   costs nothing when the columns collapse.

   Its own rules rather than the museum's panel styles: a form is the one place
   on this site where the chrome has to be louder than the artwork, because an
   input nobody can see the edges of is an input nobody fills in.
   ========================================================================== */
.band--contact { padding-bottom: clamp(30px, 4.4vw, 64px); }

.cform {
  display: grid; gap: clamp(22px, 3vw, 48px);
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  align-items: start; align-content: start;
}
.cform__lede, .cform__panel { min-width: 0; }

.cform__eyebrow {
  margin: 0 0 10px;
  font-size: 10px; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--cyan);
}
.cform__title {
  margin: 0 0 14px;
  font-size: clamp(28px, 4vw, 54px); font-weight: 800;
  line-height: 1.02; letter-spacing: -.02em; text-transform: uppercase;
  overflow-wrap: break-word;
}
.cform__title span { display: block; }
.cform__title .is-accent { color: var(--cyan); }

.cform__strap { margin: 0; color: var(--ash); font-size: 15px; }
.cform__strap span { display: block; }

.cform__notes { margin: clamp(22px, 2.6vw, 34px) 0 0; padding: 0; list-style: none;
                display: grid; gap: 12px; }
.cform__notes li {
  padding: 14px 16px; border-left: 2px solid var(--cyan);
  background: rgba(47, 228, 255, .05); border-radius: 0 10px 10px 0;
}
.cform__notes h3 { margin: 0 0 4px; font-size: 13.5px; font-weight: 700; }
.cform__notes p  { margin: 0; color: var(--ash); font-size: 13.5px; overflow-wrap: break-word; }
.cform__go { color: var(--cyan-2); white-space: nowrap; }
.cform__go:hover { text-decoration: underline; }

.cform__panel {
  padding: clamp(18px, 2.4vw, 32px);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--hairline-lo); border-radius: 18px;
}

.cform__form { display: grid; gap: 16px; }
.cform__form .fld { display: grid; gap: 5px; }
.cform__form .fld__label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ash);
}
.cform__form .fld__in {
  width: 100%; padding: 12px 14px;
  background: rgba(5, 6, 14, .6); color: var(--ice);
  border: 1px solid var(--hairline); border-radius: 10px;
  font: inherit; font-size: 15px;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.cform__form .fld__in:focus {
  outline: none; border-color: var(--cyan);
  box-shadow: 0 0 0 3px rgba(47, 228, 255, .18);
}
/* Vertical only: a horizontal drag would push the textarea out of the panel. */
.cform__form .fld__in--area { resize: vertical; min-height: 150px; line-height: 1.6; }
.cform__form .fld__note { margin: 1px 0 0; color: var(--ash-dim); font-size: 12.5px; }

/* THE HONEYPOT. Off-screen rather than display:none or visibility:hidden --
   both of those are the first thing a spam script checks for, and a field it
   can see is hidden is a field it knows to leave alone. Which is also why it
   keeps a real label and a real id. */
.cform__hp {
  position: absolute !important;
  left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden;
}

.cform__turnstile { margin: 4px 0 2px; min-height: 65px; }
.cform__go-row { margin: 4px 0 0; }
.cform__again { margin: 18px 0 0; }
.lnkish { color: var(--cyan-2); font-size: 13.5px; }
.lnkish:hover { text-decoration: underline; }

.cnote {
  margin: 0 0 18px; padding: 14px 16px; border-radius: 11px;
  border-left: 3px solid var(--cyan); background: rgba(47, 228, 255, .07);
  font-size: 14px;
}
.cnote p:first-child { margin-top: 0; }
.cnote p:last-child, .cnote ul:last-child { margin-bottom: 0; }
.cnote ul { margin: 8px 0 0; padding-left: 20px; }
.cnote--ok   { border-color: var(--cyan); background: rgba(47, 228, 255, .07); }
.cnote--warn { border-color: var(--red);  background: rgba(255, 45, 79, .09); }
.cnote code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .9em; padding: 1px 5px; border-radius: 5px;
  background: rgba(47, 228, 255, .12); color: var(--cyan-2);
}

@media (max-width: 860px) {
  .cform { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Holding together when text is scaled up

   The accessibility panel can enlarge every font on the page without making
   the window any wider. These are all the same bug: a grid or flex child
   defaults to a minimum size of its own content, so it refuses to shrink and
   pushes out of its container instead of wrapping inside it. Nothing changes
   at normal text size, because nothing is being squeezed.

   Caught on Game Domain, where a nowrap button and an unshrinkable headline
   both ran off the side at 1.5x text. Same engine, same shapes, same fix.
   -------------------------------------------------------------------------- */
.btn { white-space: normal; max-width: 100%; text-align: center; }
.hero__copy, .hero__title, .hero__lede { max-width: 100%; min-width: 0; }
.hero__title, .hero__lede { overflow-wrap: break-word; }
/* The divider band's one line of text, for the same reason -- it is a single
   centred phrase with nothing to wrap onto until it is allowed to. */
.divider__text { max-width: 100%; min-width: 0; overflow-wrap: break-word; }
.head { flex-wrap: wrap; }
.nav__list { flex-wrap: wrap; }

/* ==========================================================================
   Account menu

   The button IS a .tool, so it inherits the circle, the size and the hover
   wash. This only adds what a <button> does not get for free.
   ========================================================================== */
.acct { position: relative; display: flex; }
.acct__btn { border: 0; background: none; color: inherit; cursor: pointer; padding: 0; }
.acct.is-open .acct__btn { background: rgba(47, 228, 255, .18); }

.acct__menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  min-width: 212px; padding: 8px;
  background: rgba(10, 13, 26, .97);
  border: 1px solid var(--hairline); border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
  backdrop-filter: blur(10px);
}
/* hidden is an attribute, and a display rule anywhere can beat it by
   specificity. Stated explicitly so the menu cannot be left visible by a future
   rule that happens to set display on a descendant of .head__tools. */
.acct__menu[hidden] { display: none; }

.acct__who {
  margin: 2px 8px 8px; padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline-lo);
  font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ash-dim);
}
.acct__list { margin: 0; padding: 0; list-style: none; }
.acct__link {
  display: block; padding: 9px 10px; border-radius: 9px;
  font-size: 12.5px; font-weight: 600; color: var(--ice);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.acct__link:hover { background: rgba(47, 228, 255, .14); color: var(--cyan-2); }
/* An inert entry has no href, so it is not a link and must not look like one. */
.acct__link[aria-disabled="true"] { color: var(--ash-dim); cursor: default; }
.acct__link[aria-disabled="true"]:hover { background: none; color: var(--ash-dim); }
