/* ==========================================================================
   victory-align.css — the shared alignment and proximity system
   --------------------------------------------------------------------------
   One place where the three Victory cases agree about spacing, about which
   typeface owns which role, and about how copy attaches to a rule.

   The scale is 8 / 12 / 16 / 24 / 32 / 48 / 64.  Nothing here invents a
   seventh value; a relationship that needs changing is changed on its shared
   rule, not patched locally.

   Public Sans owns supporting copy, labels and controls.  Source Serif 4
   keeps the expressive headline and quotation roles.  Making the supporting
   roles agree is not the same as making every role one size: display scale
   stays loud on purpose.

   The optical half of this file is victory-align.js.  CSS can align boxes;
   only measured font metrics can align the first cap line or the last
   baseline of real text, and only after the fonts have actually loaded.
   ========================================================================== */

.vic{
  /* the spacing scale */
  --vs-1:8px;  --vs-2:12px; --vs-3:16px; --vs-4:24px;
  --vs-5:32px; --vs-6:48px; --vs-7:64px;

  /* the shared relationships, desktop */
  --va-rule-copy:24px;      /* rule above supporting text -> its first cap line */
  --va-label-statement:16px;/* small label -> the large statement below it     */
  --va-intro-controls:24px; /* introductory paragraph -> the controls below it */
  --va-artifact-transport:24px; /* artifact or copy -> its transport           */
  --va-gutter:56px;         /* two-column narrative gutter, 48-64              */

  /* supporting copy roles */
  --va-support-size:16px;   --va-support-lh:24px;
  --va-label-size:12px;     --va-label-lh:18px;
}

@media (max-width:767px){
  .vic{
    --va-rule-copy:16px;
    --va-intro-controls:16px;
    --va-artifact-transport:16px;
    --va-gutter:var(--vs-4);
  }
}

/* --- the supporting-copy role -------------------------------------------
   Every equivalent supporting role takes the same family, size, line height,
   weight and tracking.  A role that needs to be quieter changes colour, not
   size.                                                                    */
.vic .va-support,
.vic .va-support p,
.vic .va-support li{
  font-family:var(--v-ui);
  font-size:var(--va-support-size);
  line-height:calc(var(--va-support-lh) / var(--va-support-size));
  font-weight:400;
  letter-spacing:0;
  color:var(--v-ink-mute);
  margin:0;
}
.vic .va-support strong,.vic .va-support b{font-weight:600;color:var(--v-ink)}

/* --- the small label role -----------------------------------------------
   COLOUR OWNERSHIP. The default label colour is the environment's ink, stated
   here rather than arrived at. It used to be `var(--v-ink-label)`, which the
   environment's element-level reading-copy rule outranked on every <p>, <li>,
   <dd>, <dt>, <figcaption> and <blockquote> — so in practice the declaration
   below decided the colour of a <span> label and nothing else, and the two
   disagreed on screen. That rule now excludes labels (see victory-environment
   .css), which leaves this the owner and makes the rendered result the same
   one on every element type.

   `var(--v-ink)` and not a literal, because a surface that carries its own ink
   redeclares that token together with its background — `.vic-paper` and the
   artefact-on-paper block set `color`, `--v-ink`, `--v-ink-mute`, `--v-edge`
   as a set — and a label sitting on one of those surfaces has to follow the
   surface it is printed on, not the environment behind it.

   This stays at (0,2,0) on purpose. Every component that wants a different
   label colour already outranks it and keeps working untouched: the photo
   source line and the provenance summary in victory-grid.css, the Night Road
   environment label in victory-case.css, the cross-link keys in
   victory-identity.css. `--v-ink-label` is what those components opt into by
   name; it is a deliberate choice at a component boundary, not the default. */
.vic .va-label{
  font-family:var(--v-ui);
  font-size:var(--va-label-size);
  line-height:calc(var(--va-label-lh) / var(--va-label-size));
  font-weight:600;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--v-ink);
  margin:0;
}

/* A label sitting directly above a large statement.  The measured clearance
   is applied by victory-align.js; this is the fallback and the box floor. */
.vic .va-label + .va-statement,
.vic .va-label + h1,
.vic .va-label + h2,
.vic .va-label + h3{margin-top:var(--va-label-statement)}

/* --- rules --------------------------------------------------------------
   .va-rule is the hairline itself.  A row that hangs beneath one carries
   data-va-caprow; a row that sits above one carries data-va-baserow.  The
   script converts the declared inset into real padding once it can measure
   where the cap line and the last baseline actually fall.                  */
.vic .va-rule{border:0;border-top:1px solid var(--v-edge-soft);margin:0;height:0}

.vic [data-va-caprow]{padding-top:var(--va-rule-copy)}
.vic [data-va-baserow]{padding-bottom:var(--va-rule-copy)}
/* Once measured, the script writes the exact per-item padding and sets this
   flag, so the row's own blanket inset stops double-counting. */
.vic [data-va-caprow][data-va-measured]{padding-top:0}
.vic [data-va-baserow][data-va-measured]{padding-bottom:0}

/* --- proximity ----------------------------------------------------------- */
.vic .va-intro + .va-controls,
.vic .va-intro + [data-va-controls]{margin-top:var(--va-intro-controls)}
.vic [data-va-transport]{margin-top:var(--va-artifact-transport)}

/* --- two-column narrative ------------------------------------------------ */
.vic .va-two{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--va-gutter);
  align-items:start;
}
/* Stack before either measure becomes cramped rather than at a round number. */
@media (max-width:899px){
  .vic .va-two{grid-template-columns:minmax(0,1fr);gap:var(--vs-5)}
}

/* --- shared parent grid --------------------------------------------------
   A section introduction and the exhibit it introduces share one grid, so a
   heading, a caption and an artifact edge line up on the same columns rather
   than each carrying its own offset.                                       */
.vic .va-grid{
  display:grid;
  grid-template-columns:repeat(12,minmax(0,1fr));
  column-gap:var(--vs-4);
  align-items:start;
}
.vic .va-grid > *{min-width:0}
@media (max-width:899px){
  .vic .va-grid{grid-template-columns:minmax(0,1fr);row-gap:var(--vs-5)}
  .vic .va-grid > *{grid-column:1 / -1 !important}
}

/* Every case-study exhibit shares one left edge on a phone. */
@media (max-width:767px){
  .vic .va-flush{padding-left:0;padding-right:0}
}

/* --- a row of equals -----------------------------------------------------
   Items that read as one row keep one type style and one cap line.  Their
   interactive states differ by colour and rule, never by size, so nothing
   shifts when a pointer arrives.                                           */
.vic .va-row{
  display:flex;
  flex-wrap:wrap;
  gap:var(--vs-4) var(--va-gutter);
  align-items:flex-start;
}
.vic .va-row > *{min-width:0;margin:0}
.vic .va-row a{
  font-family:var(--v-ui);
  font-size:var(--va-support-size);
  line-height:calc(var(--va-support-lh) / var(--va-support-size));
  font-weight:600;
  color:var(--v-ink);
  text-decoration:none;
  border-bottom:1px solid var(--v-accent);
  padding-bottom:2px;
  display:inline-flex;
  align-items:baseline;
  gap:.5em;
}
.vic .va-row a:hover,.vic .va-row a:focus-visible{color:var(--v-accent)}
/* The arrow sits on the text's own baseline, not on the line box. */
.vic .va-row a .va-arrow{font-size:.95em;line-height:1;transform:translateY(-.02em)}

/* --- long-word safety ----------------------------------------------------
   Kept from the narrow-width work: nothing in a case-study grid may impose a
   min-content width wider than the screen.                                 */
.vic .va-grid > *,.vic .va-two > *,.vic .va-row > *{overflow-wrap:break-word}

/* --- reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion:reduce){
  .vic [data-va-fade]{transition:none !important}
}

/* --- hidden means hidden ---------------------------------------------------
   Several component rules in these cases set `display` on an element that also
   carries the hidden attribute.  A class selector outranks the user-agent's
   [hidden] rule, so the element keeps painting.  That failure is never wanted
   and is easy to reintroduce, so it is settled once here.  (hidden="until-found"
   is deliberately left alone; nothing in these cases uses it.)             */
.vic [hidden]:not([hidden="until-found"]){display:none !important}
