
/* ---- palette treatment: A / Wall — yellow-leaning warm -------------------------------------------------------
   Sima, 2026-08-24: "play around with different palettes, for the three versions ... with
   those combinations". Same three brand colours in all three; what changes is which one the
   page is TINTED toward. Two constraints she set are held everywhere: buttons stay purple,
   section labels stay green. So the variation lives in the grounds and the rules, not in the
   controls -- which is also why it reads as one brand in three moods rather than three brands.

   Light only. The dark-theme block in base.css uses :root:not([data-theme="light"]), which
   outranks this plain :root, so dark is untouched by design.
   A is photograph-led and its hero is near-black, so yellow does the signature work there.
   The page around it stays warm and paper-like so the photographs stay the loudest thing. */
:root {
  --ground:      #F8F7F2;   /* warm paper, a touch further toward the yellow */
  --surface-2:   #F0EEE4;
  --line:        #DEDBCC;
  --line-soft:   #EBE9DE;
}

.director { padding-block: clamp(3.5rem,8vw,6rem); }
.director::before { content:""; position:absolute; inset:0; z-index:1;
  background: linear-gradient(180deg, rgba(10,12,17,.88) 0%, rgba(10,12,17,.78) 100%); }
.director-backdrop { filter: saturate(1.05); }
.director-in { color:#fff; }
.director-portrait img { border-radius: 2px; box-shadow: 0 18px 50px rgba(0,0,0,.45); }
/* Green across the board, per Sima -- on this dark band the fluorescent one, which reads at
   10.3:1 here where --accent-green would be 3.07:1. Same colour decision, legible ground. */
.director .eyebrow { color: var(--green-bright); opacity: 1; }
.director-headline q { font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.7rem,4.2vw,2.9rem); line-height:1.08; letter-spacing:-.035em; display:block; }
.director-message p, .director-closing { color: rgba(255,255,255,.86); }
.director-attrib b, .director-attrib span { color:#fff; }
.director-cta { margin-top: 1.4rem; display: flex; flex-direction: column;
  align-items: flex-start; gap: .8rem; }
.director-signoff { font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.05rem, 2.2vw, 1.35rem); letter-spacing: -.015em; color: #fff; }

/* The frame belongs to the PHOTOGRAPH, not to the caption. Anchoring it to the whole
   figure ran the border straight through her name. Scope it to the image instead. */

.pillars { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(17rem,1fr)); margin-top: 2rem; }
.pillars article { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.pillars img { aspect-ratio: 3/2; object-fit: cover; width: 100%; }
.pillars .in { padding: 1.05rem 1.15rem 1.3rem; display: flex; flex-direction: column; gap: .5rem; }
.pillars h3 { font-size: 1.1rem; line-height: 1.25; }
.pillars p { font-size: .93rem; color: var(--ink-soft); line-height: 1.5; }

.hero {
  position: relative; min-height: min(92svh, 54rem);
  display: grid; align-items: end;
  /* Fixed dark, NOT var(--ink). Everything in this band -- h1, .kicker, .sub, the ghost button
     border -- is hardcoded #fff, because the band is a photograph with a dark scrim over it. A
     theme token flips: in dark mode --ink resolves to #EDEDE8, so if the hero image ever fails to
     load, the fallback is white text on a near-white ground at 1.17:1, which is invisible. Every
     other var(--ink) background on the site pairs with color: var(--ground) and flips in step,
     which is why this was the only one that could break.
     Value matches the scrim's own base (rgba(10,12,17,...)) so the fallback looks intentional. */
  background: #0A0C11; overflow: hidden;
}
.hero-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: .82;
}
/* The hero crossfades across the first five walls. Opacity targets .82 rather than 1 because
   that is what .hero-img sits at -- animating to full would make each slide punch brighter than
   the still beneath it and read as a flicker. The first image is NOT in this animation: it is a
   plain <img> underneath, so the largest-contentful-paint is a real decode. */
.hero-stack { position: absolute; inset: 0; }
.hero-slide {
  opacity: 0; animation-name: heroFade; animation-duration: var(--hero-cycle, 30s);
  animation-iteration-count: infinite; animation-timing-function: ease-in-out;
}
@keyframes heroFade {
  0%   { opacity: 0 }
  3%   { opacity: .82 }
  17%  { opacity: .82 }
  20%  { opacity: 0 }
  100% { opacity: 0 }
}
/* "Do not move things" -- not "move them faster". Stops on the first wall. */
@media (prefers-reduced-motion: reduce) { .hero-slide { animation: none; opacity: 0; } }
.hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,12,17,.62) 0%, rgba(10,12,17,.12) 32%, rgba(10,12,17,.88) 100%);
}
.hero-in { position: relative; padding-block: 3rem 3.4rem; color: #fff; }
.hero h1 {
  font-size: clamp(2.6rem, 8.5vw, 6rem); font-weight: 800;
  letter-spacing: -.045em; max-width: 16ch; color: #fff;
}
.hero .kicker {
  /* EMPOWER. CONNECT. TRANSFORM. glows through CITYarts' own four brand colours.
     Sima, on the 2026-08-24 recording: "I would love for the words empower connect transform to
     kind of glow from color orange the color yellow green purple".
     Those four are not a palette chosen to sit beside the logo -- they were SAMPLED OUT OF IT,
     pixel by pixel, from the four brushstroke letters of "arts". See content.brandColors.
     It sits on a dark photograph, which is the only ground where all four stay legible; every
     one of them fails against the light page. */
  color: #FCCD38; opacity: 1; font-family: var(--font-ui); font-size: .72rem;
  font-weight: 700; letter-spacing: .18em; text-transform: uppercase; margin-bottom: 1rem;
  animation: kickerGlow 16s ease-in-out infinite;
  /* "somehow it still blends in the back ... these words get lost" -- Sima, 2026-08-28. She liked
     the glow and the colours, so the fix is contrast, not restyling: the line now sits on its own
     dark plate with a heavier scrim behind it, gets larger, and the tracking opens up. The
     photograph underneath is untouched -- she also said "still beautiful" -- and darkening the
     whole image to rescue one line would have cost the wall to save the words. */
  display: inline-block; padding: .5rem .9rem; border-radius: var(--r);
  background: rgba(10, 12, 17, .55); backdrop-filter: blur(3px);
  font-size: .84rem; letter-spacing: .22em;
}
/* "adjust the font in the hero image so that it's in one line or stacked with each part of the
   statement kept together" -- Sima, 2026-08-24. Each sentence is its own inline-block, so the
   headline either fits on one line or breaks BETWEEN sentences. It can no longer split
   "Your story." across two lines, which is what it was doing.
   text-wrap:balance is deliberately overridden: balancing works by breaking wherever it likes,
   including inside a span, which is exactly the thing being prevented. */
.hero-h1 { text-wrap: normal; }
.hero-h1 span { display: inline-block; white-space: nowrap; }
@keyframes kickerGlow {
   0%  { color:#F16925; text-shadow: 0 0 18px rgba(241,105,37,.55); }
  25%  { color:#CACB2F; text-shadow: 0 0 18px rgba(202,203,47,.55); }
  50%  { color:#7A68AE; text-shadow: 0 0 22px rgba(122,104,174,.75); }
  75%  { color:#FCCD38; text-shadow: 0 0 18px rgba(252,205,56,.55); }
 100%  { color:#F16925; text-shadow: 0 0 18px rgba(241,105,37,.55); }
}
/* "Do not move things" means do not cycle a colour either. Rests on the yellow. */
@media (prefers-reduced-motion: reduce) {
  .hero .kicker { animation: none; color: #FCCD38; text-shadow: none; }
}
.hero .sub {
  margin-top: 1.1rem; font-size: clamp(1.05rem, 2.3vw, 1.3rem);
  color: #fff; opacity: .93; max-width: 34rem; line-height: 1.45;
}
.hero-cta { margin-top: 1.9rem; display: flex; gap: .7rem; flex-wrap: wrap; }
.hero-cta .btn-ghost { color: var(--accent-light); border-color: var(--accent-light); }
.hero-cta .btn-ghost:hover { color: #fff; border-color: #fff; }

/* Sima, 2026-08-24: "I like the nav treatment in the option 'See exactly'" -- variant B. What she
   is pointing at is not the type, which is already shared, but the BAR: B's masthead is sticky and
   solid and follows you down the page, where A's was transparent, painted over the photograph, and
   scrolled away at the first flick.
   The bar is now lifted out of .hero entirely rather than floated inside it. Keeping it absolute
   and merely adding a background would have left it sitting on top of its own photograph with the
   scrim showing through the gap. Out of the band, the photo starts cleanly beneath it.
   Real cost, stated: A's premise is that a stranger has given CITYarts two seconds and they should
   go on a wall, and a solid bar takes a strip of that. The trade is that nav and the "I am..."
   picker stay reachable for the whole scroll, which is what the audience routing needs. */
.masthead {
  /* White, not --ground. Sima, 2026-08-24: "remove gray highlighting in the top nav" -- the bar
     was painted in the page's own off-white (#F7F7F4), which reads as a grey band once it sits
     against a photograph. Softer rule too, so it separates without drawing a grey line. */
  position: sticky; top: 0; z-index: 40; background: var(--surface);
  border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: center; justify-content: space-between;
  padding: .75rem var(--pad); gap: 1rem;
}
.masthead .mark { font-family: var(--font-display); font-weight: 800; letter-spacing: -.02em; font-size: 1.15rem; }
.masthead nav { display: none; gap: 1.4rem; }
.masthead nav a { text-decoration: none; color: var(--ink-soft); }
.masthead nav a:hover { color: var(--ink); }
@media (min-width: 54rem) { .masthead nav { display: flex; } }


.band { padding-block: clamp(3.5rem, 8vw, 6rem); }
.band h2 { font-size: clamp(1.8rem, 4.5vw, 2.9rem); }
.band .lede { font-size: 1.18rem; color: var(--ink-soft); margin-top: 1rem; line-height: 1.5; }

/* <picture> is display:inline by default. The mosaic tile's img is width/height:100% and the
   pillar img carries an aspect-ratio -- both of which would resolve against an inline box rather
   than the figure/article, collapsing the tile. Every responsive image on this page is wrapped,
   so the wrapper has to be as transparent to layout as the bare <img> it replaced. */
.mosaic picture { display: block; width: 100%; height: 100%; }
.pillars picture { display: block; width: 100%; }
/* The hero is the third one, and it needs the opposite treatment. .hero is display:grid, and its
   only in-flow child was .hero-in -- the img is position:absolute, and so are the scrim and the
   topbar. Wrapping the img made the <picture> a real, zero-height GRID ITEM, and the hero went
   from one row to two: measured grid-template-rows 776.469px before, 193.438px 583.031px after.
   It still rendered identically (align-items:end bottom-aligns the content either way, and
   .hero-in's top stayed at 387px), which is exactly what makes it the dangerous kind of wrong.

   display:contents does NOT fix it -- measured, it leaves both rows in place. The wrapper has to
   take the same box the <img> used to have, so it is taken out of flow the same way and the img
   fills it. Back to one row of 776.469px. */
.hero picture { display: block; position: absolute; inset: 0; }

.mosaic { display: grid; gap: .5rem; grid-template-columns: repeat(4, 1fr); margin-top: 2.2rem; }
.mosaic figure { margin: 0; position: relative; overflow: hidden; border-radius: var(--r); }
.mosaic img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 1; transition: transform .5s ease; }
.mosaic figure:hover img { transform: scale(1.04); }
.mosaic figure:nth-child(1) { grid-column: span 2; grid-row: span 2; }
.mosaic figure:nth-child(1) img { aspect-ratio: 1; }
.mosaic figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: .7rem .8rem;
  background: linear-gradient(transparent, rgba(10,12,17,.85));
  color: #fff; font-family: var(--font-ui); font-size: .76rem; font-weight: 600; line-height: 1.3;
}
@media (max-width: 44rem) { .mosaic { grid-template-columns: repeat(2, 1fr); } }

.give-band { background: var(--surface-2); }
.give-band .inner { display: grid; gap: 2.2rem; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 60rem) { .give-band .inner { grid-template-columns: 1fr 1.05fr; gap: 3.5rem; } }

.voices-band { background: var(--ink); color: var(--ground); }
.voices-band .voice q { color: var(--ground); }
.voices-band cite { color: var(--on-ink-faint); }
.voices-band .eyebrow.on-ink { color: var(--green-bright); }
.voices-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); margin-top: 2rem; }
.voices-band h2 { color: var(--ground); }

.aud { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); margin-top: 2rem; }
.aud a {
  text-decoration: none; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 1.15rem 1.2rem 1.25rem;
  display: flex; flex-direction: column; gap: .35rem; transition: border-color .12s ease;
}
.aud a:hover { border-color: var(--accent); }
.aud .k { font-family: var(--font-ui); font-size: .67rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-faint); }
.aud .l { font-family: var(--font-ui); font-weight: 700; font-size: 1.02rem; }
.aud .b { font-size: .92rem; color: var(--ink-soft); line-height: 1.42; }
.aud .c { font-family: var(--font-ui); font-size: .82rem; font-weight: 700; color: var(--accent); margin-top: .3rem; }
