/*
  Frits case page styles.

  Loaded only on this page, via the pageStylesheets front-matter field
  in src/cases/frits.njk, AFTER case-shared.css (see the comment at
  the top of that file for what lives there instead: the CPRR opening
  block, the sticky sidebar/two-column layout, and the next-case
  teaser - sitewide furniture, not redefined here).

  Everything in THIS file is either Frits-specific (the hero, the
  loading-flow diagram, the before/after pair) or a CONTENT-RHYTHM
  value that legitimately differs from EIF's because Frits is a
  different presentation format (docs/Portfolio_Caseformat.md §3:
  Frits is Format A, image-led, more breathing room; EIF is Format B,
  text/reasoning-led, denser). Where a value below matches EIF's
  exactly, that was a deliberate "no reason to differ" call made
  during planning, not an oversight - see docs/iteration-protocol.md's
  "Locked sitewide values" section for the full reasoning and the
  9-item comparison this file's numbers came out of.

  IMPORTANT: like case-eif.css, this page's top-level sections do NOT
  re-apply the .site-canvas class - base.njk's <main> already wraps
  every page's content in .site-canvas once.

  File organised in the same order as the page reads, top to bottom:
    1. Hero
    2. Figure/caption primitives (this page's own rhythm, see the
       Format A note above - not the same numbers as EIF's)
    3. Sections
    4. Loading-flow diagram (section 03, visual 3a)
    5. Before/after pair (section 05)
    6. 768px responsive pass
*/

/* ==========================================================================
   1. Hero
   ========================================================================== */

.case-hero {
  padding-block: 48px 40px;
}

.case-hero__eyebrow {
  color: var(--color-accent);
  margin: 0 0 20px;
}

.case-hero__title {
  /* Matches EIF's hero title exactly (52px/1.15/48px bottom margin) -
     a deliberate "no reason to differ" call, not a leftover default.
     See docs/iteration-protocol.md's locked-values comparison.

     No max-width, unlike EIF's current hero title: at this font size,
     a 900px cap wrapped Frits' own title into three lines instead of
     two, which is a real layout defect (it also pushes the CPRR block
     down as a side effect) once actually rendered, not a stylistic
     match to preserve. Spans the full 1200px content column instead,
     same as every other full-width element on this page. */
  font-size: 52px;
  font-weight: 700;
  line-height: 1.15;
  margin: 0 0 48px;
  text-wrap: balance;
}

/* Two-layer overlapping composite, same technique as EIF's hero:
   frits-01.png (background) is the desktop step-1 "income" screen,
   frits-02.png (foreground) is the mobile "Yes! Je kunt op
   huizenjacht" screen, offset over it with a drop shadow. This is
   the CORRECTED hero per docs/Case_Frits.md ("Koen heeft de teaser
   zelf licht aangepast na oplevering") - the original Design export
   used the result screen instead, do not revert to that if re-
   deriving this from the raw export markup.

   Height is the locked "Format A hero height" (675px at the 1200px
   content column, docs/iteration-protocol.md) - a SEPARATE locked
   value from EIF's 584px, not inherited from it. EIF is Format B,
   whose brief is denser/text-led; Frits is Format A, whose brief
   explicitly calls for larger imagery and more room ("larger
   imagery, more breathing room" per Prompt_Frits_Claude_Design.md).
   Reusing EIF's 584px here was tried first and read as an awkward,
   overly tight crop once actually built - 675px is Frits' own
   number, confirmed two ways: docs/Case_Frits.md's hero visual note
   states "1200×675, 16:9" directly, and the real Design export's own
   hero scene markup literally declares `height: 675px`. A future
   Format A case reuses 675px the same way Format B cases reuse
   584px, rather than re-deriving either per case.

   Box positions below are percentages of this container, taken
   directly from that same 1200x675 scene (left/width as a fraction
   of 1200, top/height as a fraction of 675) - since the container's
   own aspect-ratio now matches that source exactly, these numbers
   reproduce the composition at its native scale, not a compressed
   one, at every width down to mobile (see the 768px section below,
   which no longer needs its own override as a result).

   No overflow: hidden here (removed): neither image's own box ever
   extends past this container at any width, so it wasn't clipping
   image content - only clipping their box-shadows once the container
   got small enough on mobile that a fixed-pixel blur radius (still
   sized for the 1200px desktop composition) no longer fit inside the
   remaining margin, which is why the foreground's shadow read as
   missing on some edges specifically on mobile. */
.case-hero__media {
  position: relative;
  aspect-ratio: 1200 / 675;
}

.case-hero__image {
  position: absolute;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  border-radius: 12px; /* locked sitewide hero-image radius */
}

.case-hero__image--background {
  left: 5.1667%;
  top: 4.4444%;
  width: 68.1667%;
  height: 83.8519%;
  box-shadow: 0 32px 64px -24px rgba(20, 24, 31, 0.18);
}

.case-hero__image--foreground {
  left: 58.3333%;
  top: 15.4074%;
  width: 21%;
  height: 71.7037%;
  box-shadow: 0 24px 48px -16px rgba(20, 24, 31, 0.22);
}

/* ==========================================================================
   2. Figure/caption primitives
   Format A rhythm: a bigger gap after the caption before the next
   paragraph (96px, vs. EIF's much tighter ~48px) is one of this
   page's deliberate "more breathing room" values - see the Format A
   note at the top of this file. Caption color matches EIF's
   (--color-body): captions carry the case's strongest claims either
   way, per Componenteninventaris.md C5, but there was no reason
   found to break from EIF's already-tuned color specifically, unlike
   the spacing values, which do have a stated reason (Format A).
   ========================================================================== */

.case-figure {
  /* Collapses against the preceding paragraph's own margin-bottom
     (20px): the larger of the two wins, so this is effectively "the
     gap before a figure is 48px," not an additive 20+48. */
  margin: 48px 0 0;
}

.case-figure__image {
  display: block;
  max-width: 100%;
  height: auto;
}

.case-figure__caption {
  max-width: 520px;
  margin: 20px 0 96px;
  padding-left: 16px;
  border-left: 2px solid var(--color-accent);
  font-size: 15px;
  color: var(--color-body);
}

/* Click-to-enlarge trigger and overlay, copied from case-eif.css
   (see case-frits-lightbox.js's header for why this is a copy, not a
   shared file). EIF only enables this on two figures; Frits enables
   it on every static figure - the credit-card modal (3b) and both
   before/after images (section 05) - since Format A leans on images
   more heavily and none of them are a hand-built diagram already
   legible at article width the way EIF's wireframe/affinity-board
   diagrams are. Excluded: the hero (branding) and the loading-flow
   diagram (a live animation, not a static image - enlarging a
   running animation is a different interaction, left out on
   purpose, not an oversight). A real button wrapping the image, not
   a div with a click handler, so it is keyboard-operable and
   announced as a control by default. */
.case-figure__trigger {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  cursor: zoom-in;
}

/* Only the before/after images (section 5's aspect-ratio-locked
   image-wrap boxes) need an explicit height here: EIF's original
   figures are natural height:auto, but these fill a fixed 4:3 box
   via object-fit:cover on the <img>, so the trigger button wrapping
   it needs to fill that same box too, not just its own width. */
.case-before-after__image-wrap .case-figure__trigger {
  height: 100%;
}

.case-figure__trigger:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 4px;
}

/* Built and inserted into the page by case-frits-lightbox.js, not
   present in the .njk markup. Hidden by the [hidden] attribute until
   opened; the explicit [hidden] rule below is needed because this
   file also sets display: flex on the bare class, which would
   otherwise win over the browser's default [hidden] { display: none }
   on equal specificity. */
.case-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 24, 31, 0.85);
  opacity: 0;
  transition: opacity 0.2s ease;
  overscroll-behavior: contain;
}

.case-lightbox[hidden] {
  display: none;
}

.case-lightbox--open {
  opacity: 1;
}

.case-lightbox--no-motion {
  transition: none;
}

.case-lightbox__image {
  display: block;
  max-width: 90vw;
  max-height: 90vh;
  border-radius: 4px;
  box-shadow: 0 32px 64px -24px rgba(0, 0, 0, 0.5);
}

.case-lightbox__close {
  position: absolute;
  top: 24px;
  right: 24px;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: var(--color-bg);
  color: var(--color-title);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
}

.case-lightbox__close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ==========================================================================
   3. Sections
   ========================================================================== */

.case-section {
  /* Matches EIF's value (40px top + 40px bottom = 80px total gap),
     reverted from an earlier Format A attempt at 112px: once actually
     built, that read as too much whitespace between sections. The
     other two Format A rhythm values (body line-height 1.72, the
     96px caption gap below) stayed - only this one didn't hold up. */
  padding-block: 40px;
  scroll-margin-top: 24px;
}

.case-layout > .case-article > .case-section:first-child {
  padding-top: 0;
}

.case-section__number {
  color: var(--color-accent);
  margin: 0 0 8px;
}

.case-section__heading {
  font-size: 30px; /* locked sitewide H2 */
  margin: 0 0 20px; /* matches EIF - no reason found to differ */
  text-wrap: balance;
}

.case-section__text {
  font-size: 18px; /* locked sitewide body text */
  line-height: 1.72; /* Format A: airier than EIF's 1.5 */
  max-width: 700px; /* matches EIF - no reason found to differ */
  margin: 0 0 20px;
}

.case-section__text:last-child {
  margin-bottom: 0;
}

/* ==========================================================================
   4. Loading-flow diagram (section 03, visual 3a)

   The case's one non-screen artefact (Format A's hard requirement,
   Portfolio_Caseformat.md §3). Two real intake-step screenshots flow
   through Diagramtaal.md-style connectors into the loading state
   (Frits' own animated mark, then five bank logos cycling through)
   and out to the result screen. Built from the real, tested keyframe
   values in reference/css-en-js/frits.css and the real connector
   coordinates in reference/css-en-js/frits-diagram-markup.html - not
   redesigned, per the project brief for this session.

   Structure: .case-flow is the whole 1200x800 composition, sized
   fluidly (100% of its column, capped at 936px, the article column
   width) via aspect-ratio: 1200/800 - NOT a fixed pixel box scaled
   with a transform. Every piece inside is positioned with
   left/top/width/height as PERCENTAGES of that 1200x800 coordinate
   system (same technique as the hero's two image layers above, see
   that section's comment for why: percentages resolve against
   whatever size the aspect-ratio-locked parent actually renders at,
   so the exact same numbers work at the 936px desktop width and
   every mobile width down to 320px, with no separate scale value to
   maintain per breakpoint). The real Design export instead uses a
   fixed-pixel scene plus a single `transform: scale(0.78)` tuned for
   one specific width - fine for a static export, not for a page that
   has to render correctly at an unpredictable range of phone widths,
   which is why this file does not copy that part of the technique
   even though the coordinates themselves come directly from it.

   To move a screen: convert its pixel left/top/width/height from the
   original 1200x800 coordinates to a percentage (divide left/width
   by 1200, top/height by 800) and edit the matching rule below.
   Nested pieces (the mark, its stripes, the bank logos) are
   percentages of THEIR OWN immediate parent's native pixel size
   instead (noted on each rule) - the same divide-by-parent's-own-
   size approach, one level at a time. The connectors SVG needs no
   conversion: an SVG viewBox already scales itself to fill its
   container, so its internal coordinates (frits.njk, viewBox is
   still 0 0 1200 800) stay exactly as extracted.
   ========================================================================== */

.case-flow {
  position: relative;
  width: 100%;
  max-width: 936px;
  aspect-ratio: 1200 / 800;
  overflow: hidden;
  background: var(--color-bg);
}

.case-flow__screen {
  position: absolute;
  overflow: hidden;
  background: var(--color-bg);
  box-shadow: 0 12px 26px rgba(11, 26, 58, 0.13), 0 3px 8px rgba(11, 26, 58, 0.07);
}

.case-flow__screen img {
  display: block;
  width: 100%;
  height: auto;
}

/* Percentages of the 1200x800 scene (left/width / 1200, top/height / 800). */

.case-flow__screen--intake {
  left: 4.3333%;
  top: 18.75%;
  width: 12.6667%;
  height: 53.125%;
  border-radius: 10px;
}

.case-flow__screen--debts {
  left: 22.3333%;
  top: 16%;
  width: 12.6667%;
  height: 58.75%;
  border-radius: 10px;
}

.case-flow__screen--loading {
  left: 41.3333%;
  top: 10%;
  width: 25%;
  height: 70.75%;
  border-radius: 14px;
  box-shadow: 0 26px 54px rgba(11, 26, 58, 0.2), 0 8px 18px rgba(11, 26, 58, 0.1);
}

.case-flow__screen--result {
  left: 75.1667%;
  top: 6%;
  width: 14.3333%;
  height: 77.25%;
  border-radius: 12px;
  box-shadow: 0 16px 34px rgba(11, 26, 58, 0.15), 0 4px 10px rgba(11, 26, 58, 0.08);
}

/* -- Frits' own mark, drawing itself: two wipe stripes + a sweeping
   circle. Decorative (aria-hidden in the markup), the caption below
   the figure carries the substantive claim. Positioned inside the
   loading screen, as a percentage of THAT screen's own native size
   (169/300, 229/566, 169/300, 170/566). */

.case-flow__mark {
  position: absolute;
  left: 21.6667%;
  top: 40.4594%;
  width: 56.3333%;
  height: 30.0353%;
  animation: fritsGroup 7.2s linear infinite;
}

/* Sized to roughly match the bank logos it alternates with (they run
   52% of the mark box's own width) rather than the ~88% the real
   Design export uses - at that size the flourish read as oversized
   next to the bank-logo slot once actually checked at its most
   visible point in the loop. Recentred within .case-flow__mark
   after shrinking: width/height scaled by ~0.66, left/top recomputed
   so the (now smaller) box sits centered rather than anchored to the
   export's original top-left-biased offset. */
.case-flow__mark-inner {
  position: absolute;
  left: 21%;
  top: 10%;
  width: 58%;
  height: 80.1%;
}

/* Percentages of .case-flow__mark-inner's own native size
   (134/149, 45/207 for the shared stripe size; each stripe's own
   left/top the same way). */
.case-flow__stripe {
  position: absolute;
  width: 89.9329%;
  height: 21.7391%;
  transform: rotate(-10deg);
  background: #dbf2ff;
  overflow: hidden;
}

/* The darker color wipes in over the lighter one, left-to-right - a
   real element (not a background-position trick) so clip-path can
   animate it per the reference keyframes. Light-to-dark is a fresh
   call made for this build, not a correction against the Design
   reference (which runs the wipe the other way) - the brief didn't
   specify a direction either way. */
.case-flow__stripe::after {
  content: "";
  position: absolute;
  inset: 0;
  background: #3ba1f5;
}

.case-flow__stripe--a {
  left: 1.8456%;
  top: 5.314%;
}

.case-flow__stripe--a::after {
  animation: fritsWipeA 7.2s cubic-bezier(0.33, 0, 0.2, 1) infinite;
}

.case-flow__stripe--b {
  left: 7.2148%;
  top: 35.7488%;
}

.case-flow__stripe--b::after {
  animation: fritsWipeB 7.2s cubic-bezier(0.33, 0, 0.2, 1) infinite;
}

/* Percentages of .case-flow__mark-inner's own native size
   (75/149, 75/207, 26.5/149, 132.5/207). border-radius: 50% still
   forms a true circle at any rendered size: width% and height% both
   derive from the same aspect-locked ancestor chain, so they never
   distort relative to each other. */
.case-flow__sweep {
  position: absolute;
  left: 17.7852%;
  top: 64.0097%;
  width: 50.3356%;
  height: 36.2319%;
  border-radius: 50%;
  background: conic-gradient(from 90deg, #4bff7d var(--frits-ang), rgba(0, 0, 0, 0) 0);
  animation: fritsSweep 7.2s cubic-bezier(0.4, 0, 0.3, 1) infinite;
}

/* -- Five bank logos, cycling one at a time in the same spot the
   mark occupies, staggered so the group reads as a carousel rather
   than five things flashing together. Decorative, alt="" in markup -
   the point is "many lenders compared", not any one bank's identity.
   Same percentage box as .case-flow__mark above (they occupy the
   same spot in the loading screen). */

.case-flow__banks {
  position: absolute;
  left: 21.6667%;
  top: 40.4594%;
  width: 56.3333%;
  height: 30.0353%;
  display: grid;
  place-items: center;
}

/* aspect-ratio: 1 (rather than a percentage height) sidesteps any
   ambiguity around percentage heights inside a grid item - width%
   alone, relative to .case-flow__banks' own resolved width, is
   enough to keep every logo square and proportional (88/169 of the
   bank box's native width). */
.case-flow__bank {
  position: absolute;
  width: 52.071%;
  aspect-ratio: 1;
  opacity: 0;
}

.case-flow__bank--1 {
  animation: bankSlot 7.2s ease-in 2.2s infinite;
}
.case-flow__bank--2 {
  animation: bankSlot 7.2s ease-in 3.2s infinite;
}
.case-flow__bank--3 {
  animation: bankSlot 7.2s ease-in 4.2s infinite;
}
.case-flow__bank--4 {
  animation: bankSlot 7.2s ease-in 5.2s infinite;
}
.case-flow__bank--5 {
  animation: bankSlot 7.2s ease-in 6.2s infinite;
}

/* SVG viewBox scaling handles the responsiveness on its own -
   width/height: 100% is all this needs, no percentage conversion. */
.case-flow__connectors {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Custom property driving the sweep circle's conic-gradient angle.
   Registering it lets the browser animate the angle smoothly instead
   of snapping between values - the same @property fallback pattern
   used sitewide for the homepage hover glow (see
   Handoff_Code_Fase.md). Without @property support, the sweep just
   doesn't animate; the rest of the loop still runs. */
@property --frits-ang {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

/* Exact keyframes from reference/css-en-js/frits.css - real, tested
   animation code, not redesigned here. */
@keyframes fritsGroup {
  0%,
  30.56% {
    opacity: 1;
  }
  32.5% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@keyframes fritsWipeA {
  0%,
  2.78% {
    clip-path: inset(0 100% 0 0);
  }
  11.11% {
    clip-path: inset(0 0 0 0);
  }
  100% {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes fritsWipeB {
  0%,
  11.11% {
    clip-path: inset(0 100% 0 0);
  }
  19.44% {
    clip-path: inset(0 0 0 0);
  }
  100% {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes fritsSweep {
  0%,
  20.83% {
    --frits-ang: 0deg;
  }
  30.56% {
    --frits-ang: 360deg;
  }
  100% {
    --frits-ang: 360deg;
  }
}

@keyframes bankSlot {
  0% {
    opacity: 0;
    transform: scale(0.92);
  }
  5.56% {
    opacity: 1;
    transform: scale(1);
  }
  13.89% {
    opacity: 1;
    transform: scale(1);
  }
  16.2% {
    opacity: 0;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1);
  }
}

/* Accessibility: freeze every animated piece at its 0% frame rather
   than letting it loop, for anyone who has asked their OS to reduce
   motion. This is a separate concern from docs/Case_Frits.md's "no
   static fallback image" note - that note is about content (there is
   no alternate still image to swap in), this is about NOT forcing
   motion on people who opted out, same sitewide pattern already used
   for the nav transition and scroll fade-ins. */
@media (prefers-reduced-motion: reduce) {
  .case-flow__mark,
  .case-flow__stripe--a::after,
  .case-flow__stripe--b::after,
  .case-flow__sweep,
  .case-flow__bank {
    animation-play-state: paused;
  }
}

/* ==========================================================================
   5. Before/after pair (section 05)
   Componenteninventaris.md C7. Desktop: side by side, 2-column grid.
   Mobile: stacked, see the 768px section below. No corner radius
   here - matches EIF's plain (non-hero) figures, radius is reserved
   for the page's actual hero image per the locked value.
   ========================================================================== */

.case-before-after {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  margin: 32px 0 0;
}

.case-before-after__label {
  font-family: var(--font-label);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 12px;
}

.case-before-after__label--after {
  color: var(--color-accent);
}

.case-before-after__image-wrap {
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.case-before-after__image-wrap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ==========================================================================
   6. 768px responsive pass
   ========================================================================== */

@media (max-width: 767px) {
  .case-hero__title {
    /* Matches EIF's mobile hero title size - same "no reason to
       differ" call as the desktop value above. */
    font-size: 32px;
  }

  /* No hero-media override needed here: since the desktop rule above
     now uses the same aspect-ratio: 1200/675 as the real mobile
     reference does (both derived from the same 1200x675 source, see
     that section's comment), one rule already covers every
     breakpoint - unlike EIF, which hides its foreground on mobile
     (case-eif.css) and would still need its own override even after
     a similar change. Frits' foreground stays visible at every width,
     a confirmed, deliberate difference from EIF, not an oversight
     (see frits.njk's hero comment). */

  .case-before-after {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  /* The next two rules override case-shared.css's furniture values
     for THIS page only (case-frits.css loads after case-shared.css).
     Real mobile reference: CPRR row padding drops from 28px to 24px,
     and next-case spacing drops from 120px/56px to 72px/28px. Scoped
     here rather than added to case-shared.css's own mobile pass,
     because EIF has no real mobile reference to confirm the same
     reduction is right for it too (see docs/iteration-protocol.md
     and Handoff_Code_Fase.md on why EIF's mobile scaffold was built
     from a written spec, not an image) - this is a deliberately
     Frits-scoped call, worth revisiting if EIB's own mobile
     reference turns out to confirm the same numbers sitewide. */
  .case-cprr__row {
    padding-block: 24px;
  }

  .case-next {
    padding-top: 72px;
    padding-bottom: 28px;
  }
}
