/* components.css — Styles scoped to UI components */

/* -- card -- */
/* One week. A phone-shaped frame with a signpost label underneath. */
.card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  cursor: pointer;
}

.card-frame {
  position: relative;
  flex: 1;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
}

.card-cover,
.card-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The video sits over the cover and fades in once it is actually playing, so */
/* there is never a black frame between the two. */
.card-video {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.card.is-active .card-video {
  opacity: 1;
}

/* One week was filmed landscape. Cover-cropping a 16:9 clip into the portrait
   card leaves a vertical strip of its middle and nothing else, so that one is
   fitted whole and the card fills in around it. The paper background is what
   makes it read as a letterbox rather than as the cover showing through. */
.card-video.is-letterboxed {
  object-fit: contain;
  background: var(--paper);
}

/* The site's editorial title style — .project-hero-title, scaled up. */
.card-label {
  flex: none;
  font-size: var(--card-label-size);
  font-weight: var(--type-title-weight);
  line-height: var(--type-title-leading);
  letter-spacing: var(--type-title-tracking);
  text-wrap: pretty;
  color: var(--quiet);
  transition: color 0.3s ease;
}

.card.is-active .card-label {
  color: var(--ink);
}

/* -- room -- */
/* The not today space itself: the door, the empty room, the measured plan. */
.room {
  display: flex;
  flex-direction: column;
  gap: 14px;
  opacity: 0.45;
  transition: opacity 0.4s ease;
}

.room.is-active {
  opacity: 1;
}

.room-frame {
  position: relative;
  flex: 1;
  overflow: hidden;
  background: var(--paper);
}

.room-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.room-label {
  flex: none;
  font-family: var(--font-not-today), sans-serif;
  font-size: var(--card-label-size);
  font-weight: 700;
  color: var(--quiet);
  transition: color 0.3s ease;
}

.room.is-active .room-label {
  color: var(--accent-ntt);
}

/* -- client -- */
/* Landscape, because these are websites and they were made for a laptop. */
.client {
  display: flex;
  flex-direction: column;
  gap: 14px;
  opacity: 0.5;
  transition: opacity 0.4s ease;
}

.client.is-active {
  opacity: 1;
}

.client-frame {
  position: relative;
  flex: 1;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
}

.client-cover,
.client-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.client-video {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.client.is-active .client-video {
  opacity: 1;
}

.client-label {
  flex: none;
  font-size: var(--card-label-size);
  font-weight: var(--type-ui-weight);
  letter-spacing: var(--type-ui-tracking);
  text-transform: uppercase;
  color: var(--quiet);
}

.client.is-active .client-label {
  color: var(--ink);
}

/* -- sign-links -- */
/* -- sign-roster -- */
/* The guest list. Three columns so thirteen names read as one block rather than
   a scroll, and the event sits under the name it belongs to. */
.sign-roster {
  columns: 3;
  column-gap: 70px;
  list-style: none;
  font-size: var(--sign-body-size);
  line-height: var(--type-body-leading);
}

.sign-roster li {
  break-inside: avoid;
  margin-bottom: 14px;
}

/* Names get the site's uppercase UI style — the same one .credits-values
   uses on a case study, which is also a list of people. */
.roster-who {
  display: block;
  font-weight: var(--type-ui-weight);
  letter-spacing: var(--type-ui-tracking);
  text-transform: uppercase;
  color: var(--ink);
}

.roster-what {
  display: block;
  font-weight: var(--type-body-weight);
  letter-spacing: var(--type-body-tracking);
  color: var(--quiet);
}

.sign-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  list-style: none;
  font-size: var(--sign-kicker-size);
  font-weight: var(--type-ui-weight);
  letter-spacing: var(--type-ui-tracking);
  text-transform: uppercase;
}

.sign-links a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--accent);
  padding-bottom: 2px;
  transition: color 0.2s ease;
}

.sign-links a:hover {
  color: var(--accent);
}

/* -- photo -- */
/* One Not Today event. Dimmed until its era is being talked about, so the */
/* wall reads as a timeline rather than fifteen equal pictures. */
.photo {
  display: flex;
  flex-direction: column;
  gap: 14px;
  opacity: 0.45;
  transition: opacity 0.4s ease;
}

.photo.is-active {
  opacity: 1;
}

.photo-frame {
  position: relative;
  flex: 1;
  overflow: hidden;
  background: var(--paper);
}

.photo-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.photo-label {
  flex: none;
  font-size: var(--card-label-size);
  font-weight: var(--type-ui-weight);
  letter-spacing: var(--type-ui-tracking);
  text-transform: uppercase;
  color: var(--quiet);
}

.photo.is-active .photo-label {
  color: var(--ink);
}

/* The three sessions before the room existed. */
.photo-live .photo-label {
  font-family: var(--font-not-today), sans-serif;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
}

/* -- sign -- */
/* Entrance, gate, bandstand, closing. Text standing in the world. */
.sign {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 34px;
}

.sign-kicker {
  font-size: var(--sign-kicker-size);
  font-weight: var(--type-ui-weight);
  letter-spacing: var(--type-ui-tracking);
  text-transform: uppercase;
  color: var(--quiet);
}

/* The site's .project-hero-title, at room scale. Its own size is the one thing
   that does not carry over — 20px is the biggest title on parc.studio, and a
   sign is read from across a room. */
.sign-title {
  font-size: var(--sign-title-size);
  font-weight: var(--type-title-weight);
  line-height: var(--type-title-leading);
  letter-spacing: var(--type-title-tracking);
  white-space: pre-line;
}

.sign-body {
  max-width: 30ch;
  font-size: var(--sign-body-size);
  font-weight: var(--type-body-weight);
  line-height: var(--type-body-leading);
  letter-spacing: var(--type-body-tracking);
  text-wrap: pretty;
  color: var(--ink);
}

.sign-body p {
  white-space: pre-line;
  break-inside: avoid;
}

.sign-body p + p {
  margin-top: 1em;
}

/* -- sign-wide -- */
/* The four prose signs carry three or more paragraphs each. In one column they
   end up taller than they are wide, and the camera frames a sign by fitting its
   whole box — a portrait sign gets zoomed out until the type is unreadable.
   Two columns keep the box landscape and the text at size. */
.sign-wide .sign-body {
  max-width: none;
  width: 960px;
  columns: 2;
  column-gap: 70px;
}

/* -- sign-note -- */
/* An aside on a sign: who we are, the desk that is coming. Set apart from the
   body so it does not get read as one more paragraph. */
.sign-note {
  max-width: 44ch;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: var(--sign-kicker-size);
  font-weight: var(--type-body-weight);
  line-height: var(--type-body-leading);
  letter-spacing: var(--type-body-tracking);
  white-space: pre-line;
  color: var(--ink);
}

/* -- cap-trim -- */
/* Every title on parc.studio is cap-trimmed: the box hugs the capitals rather
   than carrying half-leading above and below them. At 132px that half-leading
   is ~20px a side, so without this the sign titles float in their own box.
   Chrome 133+ / Safari 18.2+; older engines ignore the declaration and keep
   the untrimmed leading, which is the previous behaviour, not a broken one.

   The bottom edge is `text`, not the `alphabetic` the site uses. Trimming to
   the baseline puts descenders OUTSIDE the box, so a title ending in "public."
   spent ~28px of the 34px gap below it on the tail of the p and collided with
   the paragraph. The site can afford that at 20px; at 132px the same descender
   is 6.6x deeper. `text` keeps the font's descent inside the box, so the gap
   below a title is the same whether or not it happens to end in a descender. */
@supports (text-box: trim-both cap text) {
  .sign-title,
  .panel-title {
    text-box: trim-both cap text;
  }
}

/* -- parc-word -- */
/* The word "parc", anywhere it appears, in the parc wordmark face. */
/* Applied by App.dom.setText — never hand-written into markup. */
/* The whole rule, everywhere the word appears: the wordmark face, lowercase,
   and nothing inherited from the surrounding block. Several places set
   uppercase, a weight, or tracking on their text — the HUD, sign kickers, the
   closing links, card labels — and each of those would deform the wordmark.
   Declarations on the element itself beat inherited ones, so this holds
   without exceptions. */
.parc-word {
  font-family: var(--font-parc), sans-serif;
  font-weight: normal;
  letter-spacing: normal;
  text-transform: lowercase;
}

.sign-notToday .sign-title {
  font-family: var(--font-not-today), sans-serif;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent-ntt);
}

.sign-notToday .sign-kicker {
  color: var(--accent-ntt);
}

/* -- panel -- */
/* Only the three group stops still show a title — everything else in the world
   carries its own label, so the panel would just be repeating it. These read as
   editorial statements, so they take the case-study title style at its real
   pixel size: the HUD is the one surface read at laptop distance. */
.panel-title {
  font-size: var(--panel-title-size);
  font-weight: var(--type-title-weight);
  line-height: var(--panel-title-leading);
  letter-spacing: var(--type-title-tracking);
  margin-bottom: 10px;
  text-transform: none;
}

.panel-body {
  font-size: var(--panel-body-size);
  font-weight: var(--type-body-weight);
  line-height: var(--panel-body-leading);
  letter-spacing: var(--type-body-tracking);
  white-space: pre-line;
  text-wrap: pretty;
  text-transform: none;
  color: var(--ink);
}

.panel-note {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: var(--ui-size);
  font-weight: var(--ui-weight);
  letter-spacing: var(--ui-tracking);
  color: var(--ink);
}

/* -- hud-item -- */
.hud-item {
  color: var(--quiet);
}

.hud-item strong {
  font-weight: var(--ui-weight);
  color: var(--ink);
}

/* -- btn -- */
.btn {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--quiet);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color 0.2s ease;
}

.btn:hover {
  color: var(--ink);
}

/* -- off-path -- */
/* Only shown once someone has actually wandered. */
.return-nudge {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  color: var(--ink);
}

.hud.is-off-path .return-nudge {
  opacity: 1;
  pointer-events: auto;
}

/* -- parc-logo -- */
/* The lockup, everywhere the words "PUBLIC parc" would otherwise be typed.
   Inserted by App.dom.setText — never hand-written into markup, except the two
   places in index.html that are outside the world.

   Sized off the surrounding text rather than in fixed pixels, so the same
   element works in the HUD at 10px, on a sign kicker at 20px and mid-sentence
   in a 26px paragraph. The numbers are cap-height matching, not guesses:
   the artwork's capitals fill 24.276 of its 52px box (0.4668), Helvetica Now's
   fill 2848 of 4000 units (0.712), so 0.712 ÷ 0.4668 = 1.525em of height puts
   the two cap heights exactly level. Width follows the 219:52 artwork ratio
   (1.525 × 4.2115 = 6.424em). The artwork's baseline sits 0.6685 down its box,
   so it must hang the remaining 0.3315 × 1.525 = 0.506em below the text
   baseline for the two to share one. */
.parc-logo {
  display: inline-block;
  width: 6.424em;
  height: 1.525em;
  vertical-align: -0.506em;
}

/* -- entrance -- */
/* Flex, so the lockup is not sitting on a text baseline it has nothing to
   share with — this line is the logo and nothing else. */
.entrance-mark {
  display: flex;
  font-size: 34px;
}

.entrance-mark .parc-logo {
  vertical-align: baseline;
}

.entrance-hint {
  font-size: var(--ui-size);
  font-weight: var(--ui-weight);
  letter-spacing: var(--ui-tracking);
  text-transform: uppercase;
  color: var(--quiet);
}
