/*
 * The client-facing surface. Everything here is themed from the Client row via
 * --client-* custom properties set inline on <body>, so adding a client is a
 * database insert rather than a stylesheet edit.
 */

/* The theme is the client's decision, never the visitor's OS: repainting a
   white-labelled page to someone's dark mode pairs their accent with a
   background they never approved. */
.client[data-theme="dark"] {
  --ink: #ececec;
  --ink-soft: #a0a0a0;
  --rule: #333;
  --page: #141414;
  --panel: #1e1e1e;
}

.client[data-heading="serif"] { --font-heading: var(--font-serif); }

/* Client overrides land last so a half-filled brand kit still coheres. */
.client {
  background: var(--client-page, var(--page));
  color: var(--client-ink, var(--ink));
}

.client h1, .client h2, .client .hero__title { font-family: var(--font-heading); }

/* --- Hero ----------------------------------------------------------------- */

.hero {
  border-bottom: 3px solid var(--client-accent);
  background-color: var(--client-accent);
  background-size: cover;
  background-position: center;
}

.hero__inner {
  max-width: 1140px;
  margin: 0 auto;
  padding: 2.5rem 1.5rem;
  color: var(--client-accent-contrast);
}

/* The height tracks the width, and that is the whole point. A hero with a fixed
   height gets a wider and wider box as the viewport grows, and `cover` answers
   by scaling the image up and cropping more off the top and bottom — so St
   Patrick's church kept its spires in the preview iframe and lost them on a
   full-width monitor. Same page, cropped two different ways.

   With an aspect ratio the crop is identical at every width, which is what
   makes the preview trustworthy. min-height stops it collapsing to a strip on a
   phone, where the ratio would otherwise win; max-height stops a very wide
   monitor turning it into a billboard, and is the only width where some extra
   crop comes back. */
.hero--image {
  position: relative;

  /* width: 100% is load-bearing, not tidiness. With width left auto, the
     max-height clamp feeds back through the ratio and shrinks the *width* —
     the hero quietly stops being full-bleed and leaves a band of page colour
     down one side. A definite width means the ratio only ever decides height. */
  width: 100%;
  aspect-ratio: 25 / 9;
  min-height: 340px;
  max-height: 520px;

  /* Biased well above centre because the subject of a hero photograph is
     usually in its upper half — a church keeps its spires, a skyline its
     towers — and what gets given up is the foreground, which is the least of
     any of these pictures. It also decides what survives at the two sizes
     where the ratio cannot hold: very wide, where max-height clamps, and very
     narrow, where min-height does. 22% rather than centre is the difference
     between a complete church and a beheaded one on a wide monitor. */
  background-position: center 22%;
}

.hero--image .hero__inner {
  position: relative;
  height: 100%;
  padding: 2.5rem 1.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.6);
}

/* The scrim follows the text rather than washing the whole picture: heaviest
   behind the words, fading to nothing over the part of the photograph worth
   seeing. A flat top-to-bottom gradient does one of those jobs badly. */
.hero--image::before { content: ""; position: absolute; inset: 0; }

.hero--left.hero--image::before {
  background: linear-gradient(100deg,
    rgba(0, 0, 0, 0.78) 0%, rgba(0, 0, 0, 0.5) 42%, rgba(0, 0, 0, 0.08) 78%, rgba(0, 0, 0, 0) 100%);
}

.hero--right.hero--image::before {
  background: linear-gradient(260deg,
    rgba(0, 0, 0, 0.78) 0%, rgba(0, 0, 0, 0.5) 42%, rgba(0, 0, 0, 0.08) 78%, rgba(0, 0, 0, 0) 100%);
}

.hero--center.hero--image::before {
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.55));
}

.hero--right .hero__inner { text-align: right; align-items: flex-end; }
.hero--center .hero__inner { text-align: center; align-items: center; }
.hero--right .hero__body, .hero--center .hero__body { margin-left: auto; }
.hero--center .hero__body { margin-right: auto; }

/* Sized against the band rather than in the abstract. The hero's height now
   tracks its width, so type set for the old fixed 395px strip was left looking
   stranded in a 520px one — these ceilings keep the title at roughly a tenth of
   the hero's height across the range, which is what reads as deliberate. The vw
   term measures the iframe when previewed, so the preview scales with it. */
.hero__title {
  display: inline-block;
  font-size: clamp(1.75rem, 4vw, 3.4rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: inherit;
  text-decoration: none;
}

.hero__tagline {
  margin: 0.6rem 0 0;
  font-size: clamp(1rem, 1.55vw, 1.4rem);
  opacity: 0.92;
}

.hero__body {
  margin: 0.85rem 0 0;
  max-width: 60ch;
  font-size: clamp(0.95rem, 1.25vw, 1.15rem);
  opacity: 0.88;
}

.hero__logo { display: inline-block; }
.hero__logo img { max-height: 72px; max-width: min(100%, 340px); width: auto; display: block; }

/* A sideways fade needs width to work. On a phone there isn't any, so the
   gradient goes vertical and the text returns to the left — an angled scrim at
   400px just darkens everything unevenly. Must come after the alignment rules:
   same specificity, so source order decides. */
@media (max-width: 700px) {
  .hero--image::before,
  .hero--left.hero--image::before,
  .hero--right.hero--image::before {
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.62));
  }

  .hero--right .hero__inner,
  .hero--center .hero__inner { text-align: left; align-items: flex-start; }
  .hero--right .hero__body, .hero--center .hero__body { margin-left: 0; }
  .hero--image .hero__inner { padding: 3.5rem 1.25rem; min-height: 240px; }
}

/* --- Layout --------------------------------------------------------------- */

.client__main { max-width: 1140px; margin: 0 auto; padding: 2.5rem 1.5rem 3rem; }

.client__footer {
  padding: 1.5rem;
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
  font-size: 0.85rem;
  text-align: center;
}

/* --- Video cards ---------------------------------------------------------- */

/* auto-fit rather than a fixed three, so a client with two videos doesn't leave
   a ragged hole. */
.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}

@media (min-width: 900px) {
  .grid { grid-template-columns: repeat(3, 1fr); }
}

.card__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  color: inherit;
  text-decoration: none;
  border: 1px solid var(--rule);
  border-radius: 10px;
  overflow: hidden;
  background: var(--page);
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}

.card__link:hover, .card__link:focus-visible {
  border-color: var(--client-accent);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.09);
}

/* A 16:9 box so a missing thumbnail doesn't change the layout. */
.card__thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--panel);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.card__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card__placeholder { font-size: 1.75rem; color: var(--ink-soft); opacity: 0.5; }

.card__duration {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.card__body { padding: 0.9rem 1rem 1.1rem; }
.card__title { margin: 0; font-size: 1.05rem; line-height: 1.35; }
.card__blurb { margin: 0.4rem 0 0; color: var(--ink-soft); font-size: 0.9rem; }

/* --- One video ------------------------------------------------------------ */

.video__title { font-size: 1.5rem; margin: 0 0 1rem; }

/* Intrinsic ratio keeps the iframe responsive without JS. */
.video__frame {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  background: #000;
  border-radius: var(--radius);
}

.video__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video__description { margin-top: 1.5rem; }
.video__back { margin-top: 2rem; }

/* --- Stats a client's own audience sees ----------------------------------- */

.stats__caveat {
  background: var(--panel);
  border-left: 3px solid var(--client-accent);
  padding: 1rem 1.25rem;
  font-size: 0.92rem;
}

.stats__caveat h2 { margin: 0 0 0.5rem; font-size: 1rem; }
.stats__caveat p { margin: 0 0 0.5rem; }

/* --- The passcode gate ---------------------------------------------------- */

.unlock { max-width: 420px; margin: 3rem auto; padding: 0 1.5rem; }
.unlock h1 { font-size: 1.4rem; margin-bottom: 0.75rem; }
.unlock .errors { margin-bottom: 1rem; }
