/* Celup — Romance Flagship 1.0.0
 * Celup means dipped. This family is a length of cloth taken through a dye bath,
 * and every section of the invitation is one more dip.
 *
 * THE ONE LAW. The ground of a section is a single mix along one ramp:
 *
 *     mix(pale, deep, dip / dips)
 *
 * so every section is exactly one dip deeper than the one above it, and the step
 * is the same the whole way down whether the invitation has nine sections or
 * sixteen. The ramp is divided by the REAL number of sections the couple kept, so
 * two invitations of different lengths both run from the first dip to the last.
 *
 * AND THE RESIST NEVER TAKES A DIP. The parts the wax kept the dye out of — the
 * panels that carry account numbers, addresses and times, and the photographs —
 * stay the colour of the undyed cloth from the first section to the last. The
 * distance between the ground and the resist therefore starts narrow and ends wide:
 * measured in a browser on all five baths at the middle strength, 7.9 to 9.6 points
 * of lightness at the first dip against 21.8 to 23.5 at the last — it roughly
 * trebles. That is the one decision read a second time, and it is the reading that
 * is still visible once the deepening itself has become familiar.
 *
 * NOTHING ELSE DIVIDES ONE SECTION FROM THE NEXT. No rule, no card, no gap, no
 * shadow. Two sections are two sections because one is a dip deeper, and that is
 * the whole of it.
 *
 * WHAT THE BATH COSTS, AND WHY IT STOPS WHERE IT DOES. A ground that moves has to
 * carry the same writing at every point of its travel, and that is a harder
 * constraint than it looks. A full pale-to-near-black ramp was measured first and
 * abandoned: in the middle of such a ramp NO tone passes 4.5:1 — dark text fails
 * from about L*45 down, light text fails from about L*60 up, and there is no third
 * option. The bath therefore stops at a depth where one three-tone hierarchy still
 * holds all the way, which is measured in the contract rather than asserted here.
 *
 * AND WHAT STOPS IT IS NOT THE GROUND, IT IS THE MARK. The first solve deepened the
 * bath on its own and bought 1.5 points of lightness, because the binding voice is
 * the 10px section mark — ordinary text, owing 4.5:1 like any other, and the palest
 * of the three. The voices had to come down with the bath. Deepening them together
 * was then limited by the OTHER end: past about 28 points of travel the quiet voice
 * and the ink collapse into one another, and the midnight bath loses its voices to
 * black entirely. 28 is where all five still hold, so 28 is where the bath stops,
 * and the strongest surface preset lands exactly there: measured 26.1 to 26.2
 * points of travel, 1.75 a dip, worst text 5.03:1.
 *
 * AND BOTH ENDS OF A BATH ARE ONE HUE. A ramp from a warm pale to a cool deep
 * passes through grey in the middle — measured on the control page, and grey is
 * the one colour a wedding invitation cannot afford. Every bath keeps its hue from
 * the first dip to the last; it is the UNDYED resist that is the other colour.
 *
 * Things that are easy to get wrong here and invisible in a stylesheet read.
 *
 *   A SECOND AUTHORITY ON THE GROUND. One rule mixes the ground. A breakpoint or
 *   a preset that sets a background on a section again takes that section out of
 *   the bath, and the page still looks deliberate, because one flat section among
 *   a ramp is not obviously wrong.
 *
 *   A RESIST THAT TAKES THE DYE. The moment a panel reads --cl-pale rather than
 *   --cl-resist it starts moving with the ground and the second reading of the law
 *   is gone — at the top of the document, where they are nearly the same colour,
 *   nothing looks different at all.
 *
 *   A STRENGTH THAT OUTRUNS THE MEASUREMENT. The surface control sets how strong
 *   the bath is. The deepest declared end is what was measured for contrast, so a
 *   preset may only ever make the bath WEAKER, never stronger.
 */
/* Tokens ------------------------------------------------------------------- */
.uk-celup{
  /* THE BATH: the two ends of the ramp, in one hue. */
  --cl-pale:#E2E7F0;
  --cl-deep:#8C9BB5;
  /* THE RESIST: the undyed cloth. It never takes a dip. */
  --cl-resist:#F6F2E6;
  --cl-ink:#171B27;
  --cl-quiet:#272F40;
  --cl-mark:#512100;
  --cl-line:rgba(23,27,39,.22);
  --cl-deepshadow:rgba(23,27,39,.34);
  --cl-radius:0px;

  /* How many dips this invitation has, written by the Blade from the sections the
     couple kept, so the ramp is divided by the real number and not a constant. */
  --cl-dips:14;
  /* Which dip this section is. The fallback is the first dip, which is the only
     safe one: an element that slipped out of the bath sits at the shallow end
     rather than at a depth nobody measured. */
  --cl-dip:0;
  /* How strong the bath is. A preset may only ever make it weaker. */
  --cl-strength:.8;

  --cl-measure:30em;
  --cl-band:30em;
  --cl-pad:22px;

  --cl-display:"Lora",Georgia,Cambria,"Times New Roman",serif;
  --cl-sans:"Lora",Georgia,Cambria,"Times New Roman",serif;
  position:relative;min-height:100svh;background:var(--cl-pale);color:var(--cl-ink);
  font-family:var(--cl-sans);font-size:16px;line-height:1.62;
  -webkit-font-smoothing:antialiased;
  /* CLIP, NOT HIDDEN. overflow-x:hidden forces overflow-y to a used value of auto,
     which makes this element a scroll container and a sticky descendant then
     sticks to THIS element's scrollport instead of the window's. */
  overflow-x:hidden;
}
@supports (overflow-x:clip){.uk-celup{overflow-x:clip}}

[hidden]{display:none !important}
.uk-celup *,.uk-celup *::before,.uk-celup *::after{box-sizing:border-box}
.uk-celup img{display:block;max-width:100%}
/* Every UA margin, not only the ones that are easy to remember: blockquote, dl,
   dd, ol and ul all carry 1em, and :where() keeps the reset at zero specificity so
   it cannot outrank the components it is resetting. */
.uk-celup :where(p,blockquote,figure,ol,ul,dl,dt,dd,pre,address){margin:0}
.uk-celup :where(ol,ul){padding:0;list-style:none}
.uk-celup :where(h1,h2,h3,h4){font-family:var(--cl-display);font-weight:600;line-height:1.24;margin:0}
.uk-celup :where(button){font-family:inherit;color:inherit}

/* Shared type and ornament ------------------------------------------------- */
.uk-cl-eyebrow{font-size:11px;font-weight:700;letter-spacing:.26em;text-transform:uppercase;
  color:var(--cl-mark)}
.uk-cl-preline{white-space:pre-line}
.uk-cl-signature{font-family:var(--cl-display);font-size:21px;color:var(--cl-ink)}
.uk-cl-quote{max-width:var(--cl-measure);padding:0 0 0 18px;border-left:2px solid var(--cl-mark);
  color:var(--cl-ink);font-family:var(--cl-display);font-size:17px;font-style:italic}
.uk-cl-quote cite{display:block;margin-top:10px;font-family:var(--cl-sans);font-size:12px;
  font-style:normal;letter-spacing:.16em;text-transform:uppercase;color:var(--cl-quiet)}
.uk-cl-occasions{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;
  column-gap:8px;row-gap:4px;font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--cl-quiet)}
.uk-cl-occasions span+span::before{content:"·";padding-right:8px;color:var(--cl-mark)}
.uk-cl-button{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:46px;
  padding:11px 18px;border:1px solid var(--cl-line);border-radius:var(--cl-radius);
  background:transparent;color:var(--cl-ink);font-size:13px;font-weight:600;letter-spacing:.05em;
  text-decoration:none;cursor:pointer;transition:box-shadow .25s ease}
.uk-cl-button:hover{box-shadow:inset 0 -2px 0 var(--cl-mark)}
/* The label is --cl-resist, not a fixed cream, and the fill is --cl-ink, so the
   pair inverts with the bath instead of staying dark on a deep ground. */
.uk-cl-button.is-solid{border-color:transparent;background:var(--cl-ink);color:var(--cl-resist)}
.uk-cl-button:focus-visible,.uk-celup button:focus-visible,.uk-celup a:focus-visible{
  outline:2px solid var(--cl-mark);outline-offset:3px}

/* THE CLOTH ---------------------------------------------------------------- */
.uk-cl-sheet{position:relative;display:grid;grid-template-columns:minmax(0,1fr);
  width:min(100%,940px);margin-inline:auto;background:var(--cl-pale)}
.uk-cl-sheet > *{grid-column:1/-1}

/* A DIP, and the ONE rule that mixes a ground. Nothing else divides one section
   from the next — no rule, no card, no gap, no shadow. Two sections are two
   sections because one is a dip deeper, and that is the whole of it. */
.uk-cl-sec{position:relative;padding:40px var(--cl-pad) 44px;
  background:color-mix(in oklab, var(--cl-pale),
    var(--cl-deep) calc(var(--cl-dip) / var(--cl-dips) * var(--cl-strength) * 100%))}
/* An engine without color-mix gets the shallow end everywhere, which is the one
   state that is certainly readable: the ink was measured against the whole ramp
   and the pale end is its easiest point. */
@supports not (background:color-mix(in oklab, #000, #fff 50%)){
  .uk-cl-sec{background:var(--cl-pale)}
}

.uk-cl-body{position:relative;width:min(100%,var(--cl-band));margin-inline:auto}
.uk-cl-body > * + *{margin-top:16px}

/* THE DIP MARK: the number of the section and its name, in the one colour that is
   neither ground nor resist. */
.uk-cl-mark{display:flex;align-items:baseline;gap:12px;margin:0 0 4px;
  font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--cl-mark)}
.uk-cl-mark b{font-weight:700;font-variant-numeric:tabular-nums}
.uk-cl-mark em{font-style:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.uk-cl-title{max-width:var(--cl-measure);font-family:var(--cl-display);color:var(--cl-ink);
  font-size:clamp(21px,5.2vw,28px);text-wrap:balance}
.uk-cl-title.is-sm{font-size:clamp(16px,3.2vw,19px)}
.uk-cl-copy,.uk-cl-lead{max-width:var(--cl-measure);color:var(--cl-quiet)}
.uk-cl-lead{font-family:var(--cl-display);font-size:18px;color:var(--cl-ink)}
.uk-cl-copy{font-size:15px}

/* THE RESIST. What the guest must act on — account numbers, addresses, times — is
   on the cloth the wax kept the dye out of, so it never takes a dip. Its ring is a
   box-shadow so the panel does not grow by two pixels it did not ask for. */
.uk-cl-seam{padding:16px 18px;box-shadow:inset 0 0 0 1px var(--cl-line);background:var(--cl-resist);
  font-family:var(--cl-sans);font-size:15px;color:var(--cl-ink)}
.uk-cl-seam dt,.uk-cl-seam .uk-cl-row-mark{margin:0 0 3px;font-size:10px;font-weight:700;
  letter-spacing:.2em;text-transform:uppercase;color:var(--cl-mark)}
.uk-cl-seam dd{margin:0 0 14px;color:var(--cl-ink)}
.uk-cl-seam dd:last-child{margin-bottom:0}
.uk-cl-seam dd strong{display:block;font-weight:600;color:var(--cl-ink)}
/* :where() AROUND THE WHOLE DESCENDANT PART. As ".uk-cl-seam dd span" this is
   (0,2,1) and outranks the component class of anything placed inside a dd — the
   row of action buttons in this very panel is a <span class="uk-cl-actions">, and
   two families shipped it laid out as a BLOCK with its row gap dead. Wrapping only
   the span leaves the dd outside and the rule is still (0,1,1), which still wins. */
.uk-cl-seam :where(dd span){display:block;color:var(--cl-quiet);font-size:13px}
.uk-cl-seam .uk-cl-actions{margin-top:12px}

/* THE PAGER — this family's whole way through, and it LISTS NOTHING. Every other
   release in this catalogue navigates by showing the reader something: an index, a
   rail, a drawing, a dock, a gauge, a strip of the next thing. This one shows where
   you are and the two moves you can make from here, because a cloth is dipped once
   and then once again. The full list is still in the document, as its own section,
   for a guest who wants to jump.

   It clears the control rail at the right, so the two never sit on each other. */
.uk-cl-folio{position:fixed;z-index:30;left:14px;right:72px;
  bottom:calc(14px + env(safe-area-inset-bottom));
  display:grid;grid-template-columns:46px minmax(0,1fr) 46px;align-items:stretch;
  height:48px;background:var(--cl-resist);color:var(--cl-ink);
  box-shadow:0 4px 14px -2px var(--cl-deepshadow), inset 0 0 0 1px var(--cl-line);
  font-family:var(--cl-display)}
.uk-cl-folio button{display:grid;place-items:center;border:0;background:transparent;
  color:var(--cl-mark);cursor:pointer}
/* A spent move is plainly spent: at the first dip there is nothing before it and
   at the last there is nothing after, and a control that looks pressable and does
   nothing is worse than one that says so. */
.uk-cl-folio button[disabled]{opacity:.32;cursor:default}
.uk-cl-folio-name{display:grid;align-content:center;justify-items:center;gap:1px;
  max-width:100%;min-width:0;padding:0 8px;color:var(--cl-ink);text-decoration:none;text-align:center}
.uk-cl-folio b{font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:.18em;
  font-size:10px;color:var(--cl-mark)}
.uk-cl-folio span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:13px;letter-spacing:.03em;max-width:100%}

/* THE CONTENTS, set once in the flow. The head strip returns to it. */
.uk-cl-contents{display:grid;gap:2px}
.uk-cl-contents li{position:relative}
.uk-cl-contents a{display:grid;grid-template-columns:2.6em minmax(0,1fr);column-gap:14px;
  align-items:baseline;min-height:36px;align-content:center;color:var(--cl-ink);text-decoration:none}
.uk-cl-contents b{font-weight:400;font-variant-numeric:tabular-nums;color:var(--cl-mark);
  font-size:13px;letter-spacing:.1em}
.uk-cl-contents span{font-size:15px}
.uk-cl-contents li + li::before{content:"";position:absolute;left:0;right:0;top:-1px;height:1px;
  background:var(--cl-line)}
.uk-cl-contents li.is-here span{color:var(--cl-mark)}
.uk-cl-contents li.is-here b{font-weight:700}

/* GATE: the cloth held above the bath ------------------------------------- */
.uk-cl-gate{position:fixed;inset:0;z-index:40;display:grid;place-items:center;padding:20px;
  overflow:hidden;background:var(--cl-pale);color:var(--cl-ink);
  transition:opacity .7s ease,visibility .7s ease}
.uk-cl-gate.is-hidden{opacity:0;visibility:hidden;pointer-events:none}
.uk-cl-gate-stage{position:relative;display:grid;place-items:center;width:100%}
/* THE CLOTH BEFORE THE FIRST DIP: undyed, held above the bath. It is the one
   screen in this family that is the resist colour all over, which is also the last
   time the ground and the resist are the same thing. */
.uk-cl-gate-panel{position:relative;z-index:2;display:grid;justify-items:center;
  width:min(100% - 32px,420px);padding:30px 24px 34px;text-align:center;
  background:var(--cl-resist);box-shadow:0 16px 32px -12px var(--cl-deepshadow)}
.uk-cl-portrait{position:relative;width:100%;height:min(38svh,260px);overflow:hidden;
  background:var(--cl-resist);box-shadow:inset 0 0 0 1px var(--cl-line)}
.uk-cl-portrait img{width:100%;height:100%;object-fit:cover;
  object-position:var(--cl-focus-mobile-x,50%) var(--cl-focus-mobile-y,38%)}
.uk-cl-gate-body{position:relative;width:100%;margin-top:22px}
.uk-cl-gate-body > * + *{margin-top:14px}
.uk-cl-gate-names{font-size:clamp(26px,7.2vw,38px)}
/* THE DATE IS THE ITEM THAT MAY NOT SHRINK. A bare text node between two growing
   rules becomes an anonymous flex item with the default shrink of 1, so at 320 the
   rules took the width and the date broke across two lines with the icon stranded
   beside the first. The date is given an element of its own and refuses to shrink;
   the rules flanking it are decoration, so they are the ones that give way. */
.uk-cl-gate-date{display:flex;align-items:center;justify-content:center;gap:11px;
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--cl-quiet)}
.uk-cl-gate-date > span{flex:0 0 auto;white-space:nowrap}
.uk-cl-gate-date > svg{flex:0 0 auto}
.uk-cl-gate-date::before,.uk-cl-gate-date::after{content:"";flex:0 1 48px;min-width:0;
  height:1px;background:var(--cl-line)}
.uk-cl-couple-list{display:grid;gap:10px}
.uk-cl-couple-list span{display:grid;gap:2px}
.uk-cl-couple-list small{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--cl-mark)}
.uk-cl-couple-list strong{font-family:var(--cl-display);font-size:18px;font-weight:600}
.uk-cl-gate-open{display:flex;width:fit-content;margin-inline:auto;padding:13px 26px;
  border-color:transparent;background:var(--cl-ink);color:var(--cl-resist);font-size:14px}
/* WHAT THE GATE DOES: the cloth goes INTO the bath. It sinks, and what is under
   it is the first dip — which is the one gesture this family has, at the scale of
   the whole cloth. */
.uk-cl-gate.is-drawn .uk-cl-gate-panel{animation:uk-cl-dip .85s cubic-bezier(.3,.9,.3,1) forwards}
@keyframes uk-cl-dip{
  from{transform:translateY(0);opacity:1}
  to{transform:translateY(30px);opacity:0}}

/* COVER -------------------------------------------------------------------
   The cloth before the first dip, and the one screen with a photograph on it — so
   the one screen that carries a dark register of its own, ground and ink together,
   so no palette can leave the names the colour of the scrim behind them. */
.uk-cl-cover{--cl-resist:#121A2A;--cl-ink:#EFF1F6;--cl-quiet:#A9B2C4;
  --cl-mark:#CBA468;--cl-line:rgba(239,241,246,.22);--cl-deepshadow:rgba(0,0,0,.5);
  position:relative;display:grid;min-height:100svh;
  background:var(--cl-resist);color:var(--cl-ink)}
.uk-cl-cover-media{position:absolute;inset:0;overflow:hidden}
.uk-cl-cover-image{width:100%;height:100%;object-fit:cover;
  object-position:var(--cl-focus-mobile-x,50%) var(--cl-focus-mobile-y,38%)}
.uk-cl-cover-scrim{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(18,26,42,.24) 0%,rgba(18,26,42,.76) 58%,#121A2A 100%)}
.uk-cl-cover-empty{position:absolute;inset:0;display:grid;place-items:center;background:#172030}
.uk-cl-cover-empty-tone{position:absolute;inset:0;
  background:linear-gradient(160deg,rgba(239,241,246,.1),transparent 60%)}
.uk-cl-cover-empty-mark{position:relative;display:grid;place-items:center;height:60px;padding:0 20px;
  box-shadow:inset 0 0 0 1px var(--cl-line);
  font-family:var(--cl-display);font-size:21px;letter-spacing:.18em;color:var(--cl-ink)}
.uk-cl-cover-panel{position:relative;align-self:end;padding:48px var(--cl-pad) 60px;text-align:center}
.uk-cl-cover-panel > * + *{margin-top:14px}
.uk-cl-cover-panel .uk-cl-title{margin-inline:auto;font-size:clamp(29px,8.4vw,50px)}
.uk-cl-cover-date{display:flex;align-items:center;justify-content:center;gap:14px;
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--cl-quiet)}
.uk-cl-cover-date::before,.uk-cl-cover-date::after{content:"";flex:1 1 auto;max-width:48px;
  height:1px;background:var(--cl-line)}
/* the cover's monogram. NOT .uk-cl-mark: that name belongs to the dip marks in
   the flow, and a second rule under the same name at the same specificity would
   silently turn every one of them into this box. */
.uk-cl-monogram{display:grid;place-items:center;width:62px;height:62px;margin-inline:auto;
  box-shadow:inset 0 0 0 1px var(--cl-mark);
  font-family:var(--cl-display);font-size:14px;letter-spacing:.16em;color:var(--cl-mark)}

/* People ------------------------------------------------------------------- */
.uk-cl-people{display:grid;gap:22px}
.uk-cl-person{display:flex;align-items:flex-start;gap:14px}
.uk-cl-portrait-round{flex:0 0 auto;width:78px;height:78px;overflow:hidden;
  background:var(--cl-resist);box-shadow:0 3px 7px -2px var(--cl-deepshadow),inset 0 0 0 1px var(--cl-line)}
.uk-cl-portrait-round img{width:100%;height:100%;object-fit:cover}
.uk-cl-portrait-round.is-empty{display:grid;place-items:center}
.uk-cl-portrait-round.is-empty span{font-family:var(--cl-display);font-size:25px;color:var(--cl-mark)}
.uk-cl-person h4{margin-top:2px;font-size:20px}
.uk-cl-person > div > strong{display:block;margin-top:2px;font-size:14px;font-weight:600;color:var(--cl-mark)}
.uk-cl-parents{margin-top:8px;color:var(--cl-quiet);font-size:14px}
.uk-cl-parents span{display:block;font-size:11px;letter-spacing:.16em;text-transform:uppercase}
.uk-cl-parents em{font-style:normal;padding:0 5px;color:var(--cl-mark)}
.uk-cl-bio{margin-top:8px;color:var(--cl-quiet);font-size:14px}
.uk-cl-chapter{margin-top:18px}
.uk-cl-chapter > * + *{margin-top:10px}
.uk-cl-couple-index{display:flex;flex-wrap:wrap;column-gap:8px;row-gap:8px}
.uk-cl-couple-index button{display:inline-flex;align-items:center;gap:8px;min-height:46px;
  padding:9px 14px;border:1px solid var(--cl-line);border-radius:var(--cl-radius);
  background:transparent;cursor:pointer}
.uk-cl-couple-index button span{font-family:var(--cl-display);font-size:11px;letter-spacing:.12em;
  color:var(--cl-mark)}
.uk-cl-couple-index button.is-active{border-color:var(--cl-ink);box-shadow:inset 0 0 0 1px var(--cl-ink)}

/* Rows, events, streams ---------------------------------------------------- */
.uk-cl-rows{display:grid}
.uk-cl-row{position:relative;display:grid;gap:4px;padding:14px 0}
.uk-cl-row + .uk-cl-row{box-shadow:inset 0 1px 0 var(--cl-line)}
.uk-cl-row-mark{font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--cl-mark)}
.uk-cl-row > div > * + *{margin-top:6px}
.uk-cl-events{display:grid}
.uk-cl-event{position:relative;display:grid;gap:4px;padding:16px 0}
.uk-cl-event + .uk-cl-event{box-shadow:inset 0 1px 0 var(--cl-line)}
.uk-cl-event > div > * + *{margin-top:8px}
.uk-cl-scope{display:flex;flex-wrap:wrap;align-items:center;column-gap:8px;row-gap:6px;
  font-size:12px;color:var(--cl-quiet)}
.uk-cl-scope strong{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--cl-mark)}
.uk-cl-map{width:100%;height:190px;border:0;box-shadow:inset 0 0 0 1px var(--cl-line)}
.uk-cl-actions{display:flex;flex-wrap:wrap;column-gap:8px;row-gap:8px}
.uk-cl-streams{display:grid;gap:10px}
.uk-cl-stream{position:relative;display:flex;align-items:center;gap:12px;min-height:56px;
  padding:10px 14px;box-shadow:inset 0 0 0 1px var(--cl-line);color:var(--cl-ink);text-decoration:none}
.uk-cl-stream span{display:grid;flex:1;min-width:0}
.uk-cl-stream small{font-size:12px;color:var(--cl-quiet)}

/* Countdown ---------------------------------------------------------------- */
.uk-cl-count{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  box-shadow:inset 0 0 0 1px var(--cl-line)}
.uk-cl-count div{position:relative;display:grid;align-content:center;padding:16px 8px;text-align:center}
.uk-cl-count div + div::before{content:"";position:absolute;left:0;top:0;bottom:0;width:1px;
  background:var(--cl-line)}
.uk-cl-count strong{display:block;font-family:var(--cl-display);font-size:clamp(23px,6vw,30px);
  line-height:1.1;font-variant-numeric:tabular-nums}
.uk-cl-count span{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--cl-quiet)}

/* PHOTOGRAPHS ON THE RESIST -------------------------------------------------
   Every print is laid on a margin of the cloth the dye never reached, so the
   photographs are the one thing in the document that does not move with the bath.
   At the first dip that margin is nearly invisible; by the last it is a plain
   undyed border — the one decision read a second time, at a scale a reader meets
   head on. The mat is on the FIGURE, not on the image: a resist behind an image
   that covers it is a colour nobody ever sees. */
.uk-cl-swatch-tools{display:flex;align-items:center;justify-content:space-between;gap:10px;
  font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--cl-quiet)}
.uk-cl-swatch-tools div{display:flex;column-gap:8px}
.uk-cl-swatch-tools button{display:grid;place-items:center;width:46px;height:46px;
  border:1px solid var(--cl-line);border-radius:var(--cl-radius);background:transparent;cursor:pointer}
.uk-cl-swatch{position:relative;display:flex;overflow-x:auto;padding:6px 0 16px;
  scroll-snap-type:x mandatory;scrollbar-width:none}
.uk-cl-swatch::-webkit-scrollbar{display:none}
.uk-cl-swatch-no{position:absolute;left:0;bottom:0;z-index:3;padding:2px 8px;
  background:var(--cl-resist);color:var(--cl-mark);font-family:var(--cl-display);font-size:11px;
  letter-spacing:.06em;font-variant-numeric:tabular-nums;box-shadow:inset 0 0 0 1px var(--cl-line)}
.uk-cl-figure{position:relative;flex:0 0 auto;width:min(66vw,250px);scroll-snap-align:start;
  padding:9px;background:var(--cl-resist);
  box-shadow:0 6px 12px -3px var(--cl-deepshadow), inset 0 0 0 1px var(--cl-line)}
.uk-cl-figure img{display:block;width:100%;height:var(--cl-print,224px);object-fit:cover;
  background:var(--cl-pale)}
.uk-cl-figure button{position:absolute;right:0;top:0;z-index:3;display:grid;place-items:center;
  width:46px;height:46px;border:0;background:var(--cl-ink);color:var(--cl-resist);cursor:pointer}

/* Gift, contacts, FAQ ------------------------------------------------------ */
.uk-cl-tabs{display:flex;flex-wrap:wrap;column-gap:8px;row-gap:8px}
.uk-cl-tabs button{display:inline-flex;align-items:center;gap:7px;min-height:46px;padding:11px 15px;
  border:1px solid var(--cl-line);border-radius:var(--cl-radius);background:transparent;
  font-size:12px;font-weight:600;cursor:pointer}
.uk-cl-tabs button.is-active{border-color:var(--cl-ink);box-shadow:inset 0 0 0 1px var(--cl-ink)}
.uk-cl-gift-panel{display:block}
.uk-cl-account strong{display:block;font-family:var(--cl-display);font-size:20px;letter-spacing:.05em;
  font-variant-numeric:tabular-nums}
.uk-cl-account p{font-size:13px;color:var(--cl-quiet)}
.uk-cl-contacts{display:grid;gap:14px}
.uk-cl-contact strong{display:block;font-size:15px}
.uk-cl-contact p{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--cl-quiet)}
.uk-cl-faq{display:grid}
.uk-cl-faq-item{position:relative;padding:12px 0}
.uk-cl-faq-item + .uk-cl-faq-item{box-shadow:inset 0 1px 0 var(--cl-line)}
.uk-cl-faq-item summary{display:flex;align-items:center;justify-content:space-between;gap:10px;
  min-height:46px;cursor:pointer;font-weight:600;list-style:none}
.uk-cl-faq-item summary::-webkit-details-marker{display:none}
.uk-cl-faq-item p{margin-top:8px;color:var(--cl-quiet);font-size:15px}
.uk-cl-hashtags{display:flex;flex-wrap:wrap;justify-content:center;column-gap:8px;row-gap:8px}
.uk-cl-hashtags button{display:inline-flex;align-items:center;gap:6px;min-height:46px;padding:6px 13px;
  border:1px solid var(--cl-line);border-radius:999px;background:transparent;font-size:12px;cursor:pointer}
.uk-cl-engagement .uk-cl-body{padding-top:4px}

/* A fixed light surface cannot inherit tokens that flip with the palette: on the
   cover --cl-ink is light, so ink on this strip would measure near 1:1. */
.uk-cl-feedback{--cl-resist:#EDEFF4;--cl-ink:#1A1F2B;--cl-quiet:#49505F;
  --cl-mark:#5C3514;--cl-line:rgba(26,31,43,.22);
  position:relative;z-index:29;display:flex;align-items:center;gap:10px;
  width:min(calc(100% - var(--cl-pad) * 2),680px);margin:16px auto 0;min-height:52px;padding:10px 16px;
  box-shadow:inset 0 0 0 1px var(--cl-line);background:var(--cl-resist);color:var(--cl-ink);font-size:14px}

/* CLOSING: the last dip, and the deepest ground in the document ------------ */
/* The colophon's rung is written on the element by the markup, exactly like every
   other block the bath carried. Declaring it here as well would be a second
   authority on the one property this family is allowed to be wrong about once. */
.uk-cl-closing{position:relative;
  padding:56px var(--cl-pad) 76px;color:var(--cl-ink);text-align:center;
  background:color-mix(in oklab, var(--cl-pale),
    var(--cl-deep) calc(var(--cl-dip) / var(--cl-dips) * var(--cl-strength) * 100%))}
.uk-cl-closing-body{width:min(100%,var(--cl-measure));margin-inline:auto}
.uk-cl-closing-body > * + *{margin-top:16px}
.uk-cl-closing .uk-cl-title{margin-inline:auto;font-size:clamp(24px,6vw,34px)}
.uk-cl-closing .uk-cl-copy{margin-inline:auto}
.uk-cl-closing-share{display:flex;flex-wrap:wrap;justify-content:center;column-gap:10px;row-gap:10px}

/* Controls rail, share dialog, lightbox, toast ----------------------------- */
.uk-cl-rail{position:fixed;right:14px;bottom:calc(16px + env(safe-area-inset-bottom));z-index:24;
  display:grid;gap:8px;justify-items:center}
.uk-cl-rail-toggle,.uk-cl-rail-panel button{display:grid;place-items:center;width:46px;height:46px;
  border:1px solid rgba(239,241,246,.26);border-radius:50%;background:#151C2B;color:#EFF1F6;cursor:pointer}
.uk-cl-rail-panel{display:grid;gap:8px;justify-items:center}
.uk-cl-dialog,.uk-cl-lightbox{position:fixed;inset:0;z-index:46;display:grid;place-items:center;
  padding:20px 16px;background:rgba(14,12,8,.9);opacity:0;visibility:hidden;
  transition:opacity .3s ease,visibility .3s ease}
.uk-cl-dialog.is-open,.uk-cl-lightbox.is-open{opacity:1;visibility:visible}
.uk-cl-dialog-panel{--cl-resist:#EDEFF4;--cl-ink:#1A1F2B;--cl-quiet:#49505F;
  --cl-mark:#5C3514;--cl-line:rgba(26,31,43,.22);
  width:min(100%,430px);padding:22px;box-shadow:inset 0 0 0 1px var(--cl-ink);
  /* reads the tokens it just declared rather than repeating their hex: two
     authorities on one colour drift apart the first time one of them is edited */
  background:var(--cl-resist);color:var(--cl-ink)}
.uk-cl-dialog-panel > * + *{margin-top:14px}
.uk-cl-dialog-panel h2{font-size:21px}
.uk-cl-share-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:9px;row-gap:9px}
.uk-cl-share-grid button{display:flex;align-items:center;gap:8px;min-height:46px;padding:11px 13px;
  border:1px solid var(--cl-line);border-radius:var(--cl-radius);background:transparent;color:inherit;
  cursor:pointer;font-size:13px}
.uk-cl-dialog-close{width:100%}
.uk-cl-lightbox-panel{position:relative;width:min(100%,780px)}
.uk-cl-lightbox-panel img{width:100%;max-height:76svh;object-fit:contain;transition:opacity .2s ease}
.uk-cl-lightbox.is-switching .uk-cl-lightbox-panel img{opacity:0}
.uk-cl-lightbox-counter{margin-top:12px;color:#EFF1F6;font-size:12px;letter-spacing:.16em;text-align:center}
.uk-cl-lightbox-close,.uk-cl-lightbox-prev,.uk-cl-lightbox-next{position:absolute;display:grid;
  place-items:center;width:46px;height:46px;border:0;border-radius:50%;background:#151C2B;
  color:#EFF1F6;cursor:pointer}
.uk-cl-lightbox-close{top:-56px;right:0}
.uk-cl-lightbox-prev{left:6px;top:50%;transform:translateY(-50%)}
.uk-cl-lightbox-next{right:6px;top:50%;transform:translateY(-50%)}
.uk-cl-toast{position:fixed;left:50%;bottom:calc(22px + env(safe-area-inset-bottom));z-index:48;
  transform:translate(-50%,14px);opacity:0;padding:11px 18px;background:#151C2B;color:#EFF1F6;
  font-size:13px;pointer-events:none;transition:opacity .3s ease,transform .3s ease}
.uk-cl-toast.is-visible{opacity:1;transform:translate(-50%,0)}

/* MOTION: THE GROUND TAKES ITS DYE ----------------------------------------
   A section arrives at the shallow end of the bath and comes to its own depth — the
   one gesture of this family, at the scale of one section. The colour IS the
   movement; the small rise underneath it is only there so the arrival has a
   direction.

   THE SHALLOW START IS ARMED BY THE SCRIPT, NOT DECLARED BY THE STYLESHEET. The
   ground of a section is mixed unconditionally above, so the law is a CSS fact and
   a page whose script never ran shows the bath rather than a document of undyed
   cloth. Only once the observer has taken charge does the undipped state exist —
   and under the minimal motion preset the script does not arm it at all, because a
   state with no transition out of it is a pop, not a gesture. */
.uk-cl-sec,.uk-cl-closing{transition:background-color .9s ease}
.is-celup-observing .uk-cl-sec:not(.is-visible),
.is-celup-observing .uk-cl-closing:not(.is-visible){background:var(--cl-pale)}
.uk-cl-reveal{opacity:0;transition:opacity .5s ease,transform .62s cubic-bezier(.2,.8,.25,1)}
.uk-cl-body.uk-cl-reveal,.uk-cl-cover.uk-cl-reveal,.uk-cl-closing.uk-cl-reveal{
  transform:translateY(-14px)}
.uk-cl-reveal.is-visible{opacity:1;transform:none}
.uk-cl-reveal-item{opacity:0;transform:translateY(-9px);
  transition:opacity .5s ease var(--cl-lag,0ms),transform .5s ease var(--cl-lag,0ms)}
.uk-cl-reveal.is-visible .uk-cl-reveal-item{opacity:1;transform:none}
.uk-cl-reveal-item:nth-child(2){--cl-lag:calc(var(--cl-lag-step,0ms) * 1)}
.uk-cl-reveal-item:nth-child(3){--cl-lag:calc(var(--cl-lag-step,0ms) * 2)}
.uk-cl-reveal-item:nth-child(4){--cl-lag:calc(var(--cl-lag-step,0ms) * 3)}
.uk-cl-reveal-item:nth-child(n+5){--cl-lag:calc(var(--cl-lag-step,0ms) * 4)}

/* Design controls ---------------------------------------------------------- */
/* "Template" is the family's OWN colours, so it restates the tokens at the head of
   this file rather than a near-miss of them. Every palette declares every token: a
   palette that sets four and leaves the mark behind leaves it at the template's
   value, which on the dark cover is the one colour nobody looked at. */
.uk-design-palette-template.uk-celup{--cl-pale:#E2E7F0;--cl-deep:#8C9BB5;--cl-resist:#F6F2E6;--cl-ink:#171B27;--cl-quiet:#272F40;--cl-mark:#512100;--cl-line:rgba(23,27,39,.22);--cl-deepshadow:rgba(23,27,39,.34)}
.uk-design-palette-warm.uk-celup{--cl-pale:#F7EDD2;--cl-deep:#B69E69;--cl-resist:#FBF6EC;--cl-ink:#241905;--cl-quiet:#43320B;--cl-mark:#5D2200;--cl-line:rgba(36,25,5,.22);--cl-deepshadow:rgba(36,25,5,.34)}
.uk-design-palette-romantic.uk-celup{--cl-pale:#F9E8E6;--cl-deep:#BD9594;--cl-resist:#FBF4E8;--cl-ink:#2B1217;--cl-quiet:#52252C;--cl-mark:#6B0419;--cl-line:rgba(43,18,23,.22);--cl-deepshadow:rgba(43,18,23,.34)}
.uk-design-palette-sage.uk-celup{--cl-pale:#E7EFE3;--cl-deep:#91A58D;--cl-resist:#F7F3E7;--cl-ink:#15210F;--cl-quiet:#293722;--cl-mark:#133B09;--cl-line:rgba(21,33,15,.22);--cl-deepshadow:rgba(21,33,15,.34)}
/* The last bath. The cloth comes out of it a deep slate, and the resist is still
   the undyed warm cloth. Its undyed end is lighter than the name suggests, and that
   is what buys this bath its depth: with the first ramp's mid-grey start the voices
   ran out of room at 22 points of travel and this was the one bath that could not
   reach the other four. */
.uk-design-palette-midnight.uk-celup{--cl-pale:#D5DAE6;--cl-deep:#858EA5;--cl-resist:#E6E3D7;--cl-ink:#0E1118;--cl-quiet:#1E232F;--cl-mark:#2A1C43;--cl-line:rgba(14,17,24,.22);--cl-deepshadow:rgba(14,17,24,.4)}

.uk-design-type-classic .uk-cl-title,.uk-design-type-classic .uk-cl-gate-names{font-family:var(--cl-display)}
.uk-design-type-modern .uk-cl-title,.uk-design-type-modern .uk-cl-gate-names{font-family:var(--cl-sans);letter-spacing:.02em}
.uk-design-type-editorial .uk-cl-title{font-size:clamp(24px,6.2vw,34px);letter-spacing:-.01em}
.uk-design-type-editorial .uk-cl-cover-panel .uk-cl-title{font-size:clamp(32px,9.4vw,58px);letter-spacing:-.02em}

/* COMPOUND, not descendant. The design classes are printed onto the SAME element
   as .uk-celup, so ".uk-design-surface-soft .uk-celup" asks for a root inside a
   root and matches nothing: measured in nine shipped releases, all three presets
   left their tokens where the root put them and moved nothing at all.
   Here SURFACE IS THE STRENGTH OF THE BATH. A weak bath and a strong one are the
   only two ways to dye cloth, and the choice is measurable: every ground in the
   document moves, and the distance between the last dip and the resist changes
   with it. It cannot be dead, because the one rule that mixes a ground reads it.
   The deepest declared end is the end that was measured for contrast, so a preset
   may only ever make the bath WEAKER — never stronger than 1. */
.uk-design-surface-soft.uk-celup{--cl-strength:.55}
.uk-design-surface-balanced.uk-celup{--cl-strength:.8}
.uk-design-surface-sharp.uk-celup{--cl-strength:1}

/* The gallery presets are descendants of the root, which is where the design class
   is printed, so these selectors do match. Every print keeps its undyed mat in all
   three; what changes is how big a print is. */
.uk-design-gallery-grid.uk-celup{--cl-print:172px}
.uk-design-gallery-grid .uk-cl-figure{width:min(48vw,186px)}
.uk-design-gallery-filmstrip.uk-celup{--cl-print:224px}
.uk-design-gallery-filmstrip .uk-cl-figure{width:min(66vw,250px)}
.uk-design-gallery-editorial.uk-celup{--cl-print:288px}
.uk-design-gallery-editorial .uk-cl-figure{width:min(82vw,330px)}

/* MOTION SETS THE ORDER, NOT THE GESTURE. The gesture is a ground taking its dye,
   which is the signature; a preset that replaced it would overwrite the identity.
   Soft brings a section's blocks in together, cinematic one after another, and
   minimal brings nothing in at all.
   These three previously set --cl-settle and --cl-travel, which no rule in this
   file reads: soft and cinematic were byte-for-byte the same page. */
.uk-design-motion-soft.uk-celup{--cl-lag-step:40ms}
.uk-design-motion-cinematic.uk-celup{--cl-lag-step:110ms}
.uk-design-motion-minimal.uk-celup{--cl-lag-step:0ms}
/* And stillness is not a slow dip: a section left at the shallow end on a machine
   that asked for no motion is a page stuck mid-gesture. */
.uk-design-motion-minimal .uk-cl-reveal,
.uk-design-motion-minimal .uk-cl-body.uk-cl-reveal,
.uk-design-motion-minimal .uk-cl-cover.uk-cl-reveal,
.uk-design-motion-minimal .uk-cl-closing.uk-cl-reveal,
.uk-design-motion-minimal .uk-cl-reveal-item{opacity:1;transform:none;transition:none}
.uk-design-motion-minimal .uk-cl-sec,
.uk-design-motion-minimal .uk-cl-closing{transition:none}
.uk-design-motion-minimal .uk-cl-gate.is-drawn .uk-cl-gate-panel{animation:none}

/* Wider viewports ---------------------------------------------------------- */
@media(min-width:760px){
.uk-celup{font-size:17px;--cl-band:40em}
/* The band is sized on the wider of the two, so a side-by-side block has somewhere
   to go and the prose still starts where it always did. */
.uk-cl-sec{padding-inline:max(var(--cl-pad),calc((100% - var(--cl-band)) / 2))}
.uk-cl-portrait{height:min(34svh,280px)}
.uk-cl-portrait img,.uk-cl-cover-media .uk-cl-cover-image{
  object-position:var(--cl-focus-desktop-x,50%) var(--cl-focus-desktop-y,42%)}
.uk-cl-cover-panel{padding:64px var(--cl-pad) 78px}
.uk-cl-closing{padding:80px var(--cl-pad) 100px}
.uk-cl-people{gap:26px;grid-template-columns:repeat(2,minmax(0,1fr))}
/* An odd last person takes the row and is centred, so a pair never ends with
   somebody hanging in the left column — capped, because one portrait stretched
   across a desktop page is a banner. */
.uk-cl-people>*:last-child:nth-child(odd){grid-column:1/-1;justify-self:center;width:min(100%,400px)}
.uk-cl-portrait-round{width:92px;height:92px}
}
@media(min-width:1100px){
.uk-cl-closing{padding:96px var(--cl-pad) 118px}
}

/* Narrow phones ------------------------------------------------------------ */
@media(max-width:400px){
.uk-cl-count{grid-template-columns:repeat(2,minmax(0,1fr))}
/* two columns means two rows, and the hairline between the columns must not be
   drawn down the first cell of the second row */
.uk-cl-count div:nth-child(odd)::before{display:none}
}
@media(max-width:560px){
.uk-cl-share-grid{grid-template-columns:minmax(0,1fr)}
.uk-cl-lightbox-close{top:auto;bottom:-56px;right:50%;transform:translateX(50%)}
}

/* Short viewports: a landscape phone and a short laptop window are different
   rooms, so every height rule names the width it means. */
@media(max-height:620px) and (max-width:1024px){
.uk-cl-cover-panel{padding:24px var(--cl-pad) 30px}
.uk-cl-cover-panel .uk-cl-title{font-size:clamp(22px,5.2vw,30px)}
.uk-cl-cover-empty-mark{height:48px;font-size:17px}
.uk-cl-gate{padding:12px}
.uk-cl-portrait{height:min(26svh,150px)}
.uk-cl-gate-panel{padding:18px 20px 22px}
.uk-cl-gate-body{margin-top:14px}
.uk-cl-gate-names{font-size:clamp(20px,4.4vw,26px)}
.uk-cl-rail{bottom:calc(10px + env(safe-area-inset-bottom))}
}
@media(max-height:620px) and (min-width:1025px){
.uk-cl-portrait{height:min(30svh,210px)}
}

/* Reduced motion ----------------------------------------------------------- */
@media(prefers-reduced-motion:reduce){
.uk-celup *,.uk-celup *::before,.uk-celup *::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;transition-delay:0ms !important;scroll-behavior:auto !important}
.uk-cl-reveal,.uk-cl-body.uk-cl-reveal,.uk-cl-cover.uk-cl-reveal,.uk-cl-closing.uk-cl-reveal,.uk-cl-reveal-item{opacity:1;transform:none}
}
