/* ============================================================
   VIEWER — viewer.css
   The visitor-facing pieces the static site never needed: the
   login form, the 404, and the /work index.
   The menu lives in menu.css, shared with the admin panel.
   Requires tokens.css, global.css and case-study-template.css.
   ============================================================ */

/* ── Login / 404 ────────────────────────────────────────────*/
.auth {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: var(--head-top) var(--pad) clamp(4rem, 8vw, 7rem);
}

/* No surface behind it — the form sits on the page ground, which is
   why it can afford to be wider than a card would be. */
.auth-panel {
  width: 100%;
  max-width: 560px;
}

/* Type comes from the shared page-title role in global.css. */
.auth-panel h1 { margin: 0 0 1rem; }

.auth-note { color: var(--cream-dim); margin-bottom: 1.5rem; }
.auth-note a { color: var(--gold); }

/* The 404 has no form to line up against, so it centres on the page
   and leads with the code itself, set big in the body sans rather than
   the display serif the h1 under it uses. */
.auth-404 { text-align: center; }
.auth-404 .error-code {
  font-family: var(--font-body);
  font-size: clamp(5rem, 16vw, 11rem);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--gold);
  margin-bottom: .5rem;
}
.auth-404 .auth-note { margin-bottom: 0; text-wrap: balance; }

.auth-error {
  padding: .75rem 1rem;
  margin-bottom: 1.25rem;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(232, 64, 16, .45);
  background: rgba(232, 64, 16, .10);
  color: var(--cream);
}

.auth-panel label {
  display: block;
  margin-bottom: .4rem;
  color: var(--cream-dim);
}

.auth-panel input {
  width: 100%;
  height: 52px;
  margin-bottom: 1.25rem;
  padding: 0 1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--gold);
  background: var(--plum);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: var(--text-dek);
}
.auth-panel input:focus { border-color: var(--gold-hover); outline: none; }

/* .btn is a link elsewhere in the template; as a submit button it
   needs the browser defaults knocked off. Filled rather than outlined:
   it's the only action on the page. */
.auth-panel .btn {
  width: 100%;
  height: 52px;
  margin-top: .25rem;
  background: var(--gold);
  color: #fff;
  font-family: var(--font-body);
  cursor: pointer;
}
.auth-panel .btn:hover { background: var(--gold-hover); border-color: var(--gold-hover); }

/* ── /work — the case study index ───────────────────────────*/
.work-index-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: var(--max);
  margin: 0 auto;
  padding: var(--head-top) var(--pad) clamp(2.5rem, 4.5vw, 4rem);
  text-align: center;
}

.work-index-note { color: var(--cream-dim); max-width: 62ch; text-wrap: pretty; }
.work-index-note a { color: var(--gold); }
.work-index-empty { max-width: 52ch; margin: 0 auto; padding: 0 var(--pad) 6rem; color: var(--cream-dim); text-align: center; }
.work-index-empty a { color: var(--gold); }

/* Two big squares, centred. At rest each one is nothing but its image;
   the writing is underneath, waiting for a hover.

   Deliberately wider than the site's --max: the reading measure that
   governs prose doesn't apply to a wall of imagery. */
.work-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 3.5rem) clamp(3rem, 6vw, 6rem);
}
@media (max-width: 760px) { .work-grid { grid-template-columns: 1fr; } }

/* A fixed square, so a long title can't make one row taller than the
   next. Everything inside is absolutely placed. No keyline: the card's
   surface is a shade lighter than the page and that's enough. */
.work-box {
  /* One padding value governs the top, the sides and the arrow, so the
     text well reads as an even inset rather than three near-misses. */
  --card-pad: clamp(1.4rem, 2.2vw, 2rem);
  --work-type: clamp(1.05rem, 1.25vw, 1.25rem);
  --work-client: calc(var(--work-type) * 1.18);
  --work-line: calc(var(--work-type) * 1.35);

  /* How far the image pulls back. Proportional to the card, so a wide
     card opens a proportionally deeper well rather than the same fixed
     strip — but never shallower than a one-line client name over a
     three-line explainer with matching padding, which is the floor the
     calc describes. Big cards take the 30%; small ones take the floor. */
  --reveal: max(calc(var(--card-pad) * 2 + var(--work-line) * 4.18 + 4px), 30%);
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: inherit;
  text-decoration: none;
}

/* The image covers the card, then slides down out of the frame to
   uncover the text — barely shrinking, mostly just leaving. Its bottom
   runs past the card and is clipped, so the card is the viewport.
   Animating `inset` keeps this off the grid: the card itself never
   changes size, so nothing else on the page moves. */
.work-box-media {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--plum-soft);
  transition: inset var(--dur-slow) var(--ease), border-radius var(--dur-slow) var(--ease);
}
.work-box:hover .work-box-media,
.work-box:focus-visible .work-box-media {
  inset: var(--reveal) 3% -14% 3%;
  border-radius: var(--radius-md);
}
.work-box-media img { width: 100%; height: 100%; object-fit: cover; }

/* Marks the entries that aren't on the open site, so it's never
   ambiguous which of these a visitor could forward to someone. Sits on
   the card rather than the image, bottom-left — which is inside the
   image in both the resting and the hovered state. */
.work-box-flag {
  position: absolute;
  z-index: 4;
  bottom: 20px;
  left: 20px;
  padding: .25rem .6rem;
  border-radius: var(--radius-pill);
  background: rgba(14, 9, 7, .82);
  border: 1px solid var(--gold);
  color: var(--gold);
  font-size: var(--text-tag);
  letter-spacing: var(--tracking-tag);
  text-transform: uppercase;
}

/* Top-aligned, so the inset above the client name matches the one at
   its left. The well is always four lines tall whether the explainer
   takes one line or three, which keeps a row of cards agreeing. */
.work-box-body {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--reveal);
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--card-pad);
  padding-right: calc(var(--card-pad) + 58px); /* clears the arrow */
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur-fast) var(--ease) .1s,
              transform var(--dur-slow) var(--ease);
}
.work-box:hover .work-box-body,
.work-box:focus-visible .work-box-body { opacity: 1; transform: none; }

/* Two lines, one size, one family: the client's name carries the weight
   and the colour, the title follows it quietly. */
.work-box-client,
.work-box-body h2 {
  font-family: var(--font-body);
  font-size: var(--work-type);
  line-height: 1.35;
  letter-spacing: -.01em;
  text-transform: none;
  text-wrap: pretty;
}
.work-box-client {
  font-size: var(--work-client);
  font-weight: var(--font-weight-semibold);
  color: var(--cream);
}
.work-box-body h2 {
  font-weight: var(--font-weight-regular);
  color: var(--cream-dim);
  /* Three lines is what the well is built for; a fourth would slide
     under the image rather than push it, so cut it off instead. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

/* Same family as the carousel's nav buttons, round instead of 8px, and
   outline only — nothing here is filled. */
.work-box-go {
  position: absolute;
  z-index: 3;
  top: var(--card-pad);
  right: var(--card-pad);
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  border: 2px solid var(--gold);
  color: var(--gold);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease) .1s;
}
.work-box:hover .work-box-go,
.work-box:focus-visible .work-box-go { opacity: 1; }

/* No hover to give, so give the whole thing away. */
@media (hover: none) {
  .work-box-media { inset: var(--reveal) 3% -14% 3%; border-radius: var(--radius-md); }
  .work-box-body, .work-box-go { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .work-box-media, .work-box-body, .work-box-go { transition: none; }
}
