/* The home page's save the date: a painted card lying on the linen. Stacked on phones, side by
   side on wide screens. Sizes inside the card are in container units (cqi: a percentage of the
   card's inner width), so the whole card scales as one piece. The painted art is in
   public/art/card; see docs/draft-2.md for how it was made and prepared. */

.site-main.site-main--home {
  --margin: 3.5vw;
  max-width: none;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--margin);
}

/* The card: painted paper, lit from the upper left, lying flat on the cloth. Its width is set
   once here and its padding is a share of it (a container can't size its own padding in
   container units). It is as wide as the screen allows, and no wider than the height allows:
   the stacked content needs a card --tall times as tall as it is wide (measured, and held by
   npm run test:layout). */
.card {
  --tall: 1.96;
  --width: min(
    100vw - 2 * var(--margin),
    540px,
    max((100svh - 2 * var(--margin)) / var(--tall), var(--zoom-floor))
  );
  /* See the note on browser zoom below. */
  --zoom-floor: 0px;
  --corner-share: 0.31;
  --corner-inset: calc(var(--width) * 0.017);
  --corner-w: calc(var(--width) * var(--corner-share));
  --corner-br-w: var(--corner-w);
  /* Where the bottom-right piece's stems end (see .card__vine). */
  --br-across: 1.073;
  --br-down: 0.822;
  /* How far its fruit reaches along each edge, for the ruled line. */
  --br-reach: 0.7;
  /* The corner art's vines leave each piece 16% of its width in from the card's edge; the
     painted vine strips continue along that line. */
  --vine-line: calc(var(--corner-inset) + var(--corner-w) * 0.16);
  /* The horizontal strip is two painted variants joined end to end (4344 × 274), so the
     repeat is hard to spot on wide cards. */
  --vine: calc(var(--corner-w) * 0.226);
  /* How far each strip runs under a corner piece, fading in, before the corner's own stem ends. */
  --overlap: calc(var(--corner-w) * 0.08);
  /* A fine ruled line the vine climbs along, a touch inside its stem. */
  --rule-inset: calc(var(--vine-line) + var(--vine) * 0.1);
  --ink: #3a0f2d;
  --ink-soft: #5b2d4c;
  --amp: #6f4f93;

  position: relative;
  isolation: isolate;
  container-type: inline-size;
  box-sizing: border-box;
  width: var(--width);
  /* On a tall screen the card grows into the height, up to twice as tall as it is wide; the
     photo takes the extra room around it. */
  min-height: min(100svh - 2 * var(--margin), 2.05 * var(--width));
  padding: calc(var(--width) * 0.19) calc(var(--width) * 0.11) calc(var(--width) * 0.125);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: repeat(4, auto) 1fr repeat(5, auto);
  grid-template-areas: 'arch' 'sprig' 'eyebrow' 'names' 'photo' 'date' 'place' 'divider' 'follow' 'calendar';
  justify-items: center;
  text-align: center;
  color: var(--ink);
}
/* The card's shadow, cast by a box set just inside the deckled edge, so the notches in the edge
   show the cloth rather than a hard shadow line. A plain box shadow, not a shadow filter on the
   whole card: a filter makes the browser repaint everything on the card on every resize. */
.card::after {
  content: '';
  position: absolute;
  inset: 2.5px;
  z-index: -2;
  box-shadow:
    0.5px 1px 2px #39112b40,
    3px 7px 10px #39112b2a,
    9px 20px 30px #39112b28;
  pointer-events: none;
}
/* The paper itself, on its own layer so its edge can be deckled without touching the contents.
   The deckle is a mask: small pre-drawn strips with an irregular edge (art/deckle-*.png) along
   each side, around a solid middle. An image mask costs next to nothing to draw, unlike an SVG
   filter, which Firefox redraws slowly. */
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse 90% 70% at 25% 15%, #ffffff55, #ffffff00 70%),
    /* A wash of white: fresh cotton stock rather than old ivory, texture kept. */
    linear-gradient(#ffffff38, #ffffff38),
    url('/art/card/paper.jpg') 0 0 / 768px 768px,
    #f0e8e2;
  --deckle-masks:
    url('/art/card/deckle-top.png') top left / 512px 3px repeat-x,
    url('/art/card/deckle-bottom.png') bottom left / 512px 3px repeat-x,
    url('/art/card/deckle-left.png') top left / 3px 512px repeat-y,
    url('/art/card/deckle-right.png') top right / 3px 512px repeat-y,
    linear-gradient(#000 0 0) center / calc(100% - 6px) calc(100% - 6px) no-repeat;
  -webkit-mask: var(--deckle-masks);
  mask: var(--deckle-masks);
}

/* Browser zoom. Zooming tells the page the window got smaller, so a card fitted to the window
   would just shrink back and zoom would do nothing. In a desktop window the card fits the window
   only down to a floor in fixed pixels; zoom in past it and the card grows on screen and the
   page scrolls, as zoom should. The floors are about the card's size on a small laptop at 100%,
   so ordinary windows still fit without scrolling. Phones fit the screen (pinch-zoom magnifies
   instead). */
@media (pointer: fine), (pointer: none) {
  .card {
    --zoom-floor: 300px;
  }
}
@media (pointer: fine) and (min-width: 700px) and (min-aspect-ratio: 5/4),
  (pointer: none) and (min-width: 700px) and (min-aspect-ratio: 5/4),
  (pointer: fine) and (min-width: 960px) and (min-aspect-ratio: 4/5),
  (pointer: none) and (min-width: 960px) and (min-aspect-ratio: 4/5) {
  .card {
    --zoom-floor: 840px;
  }
}

/* The painted art is stored as paint on transparency (lifted off its white paper), so it sits
   on the card like ink and covers the ruled line where they cross. */
.card__corner {
  position: absolute;
  z-index: 1;
  width: var(--corner-w);
  height: auto;
  pointer-events: none;
}
.card__corner--tl {
  top: calc(var(--corner-inset) + var(--corner-w) * 0.006);
  left: calc(var(--corner-inset) - var(--corner-w) * 0.001);
}
.card__corner--tr {
  top: calc(var(--corner-inset) - var(--corner-w) * 0.042);
  right: calc(var(--corner-inset) + var(--corner-w) * 0.032);
}
.card__corner--bl {
  bottom: calc(var(--corner-inset) + var(--corner-w) * 0.013);
  left: calc(var(--corner-inset) + var(--corner-w) * 0.009);
}
.card__corner--br {
  bottom: calc(var(--corner-inset) + var(--corner-w) * 0.024);
  right: calc(var(--corner-inset) + var(--corner-w) * 0.073);
}
/* The vine: painted strips that repeat along each edge between the corners. Each corner piece is
   placed so its trailing stems leave exactly on the vine line (offsets measured from the art);
   each strip starts under a corner with a bare stretch of stem and fades in over the corner's
   own stem, so stem meets stem with no seam. Where a stem ends (in cw, the corner's width, from
   the card's edge): tl 0.939 across, 0.732 down; tr 0.958, 0.718; bl 0.952, 0.739; br (small)
   1.073, 0.822; br (ornate, wide screens) 1.287, 0.829. */
.card__vine {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  --fade: linear-gradient(
    var(--fade-dir),
    transparent,
    #000 var(--overlap),
    #000 calc(100% - var(--overlap)),
    transparent
  );
  -webkit-mask: var(--fade);
  mask: var(--fade);
}
.card__vine--top,
.card__vine--bottom {
  --fade-dir: to right;
  height: var(--vine);
  background: url('/art/card/vine-h.webp') left center / auto 100% repeat-x;
}
.card__vine--top {
  top: calc(var(--vine-line) - var(--vine) / 2);
  left: calc(var(--corner-inset) + var(--corner-w) * 0.939 - var(--overlap));
  right: calc(var(--corner-inset) + var(--corner-w) * 0.958 - var(--overlap));
}
.card__vine--bottom {
  bottom: calc(var(--vine-line) - var(--vine) / 2);
  left: calc(var(--corner-inset) + var(--corner-w) * 0.952 - var(--overlap));
  right: calc(var(--corner-inset) + var(--corner-w) * var(--br-across) - var(--overlap));
}
.card__vine--left,
.card__vine--right {
  --fade-dir: to bottom;
  width: calc(var(--vine) * 162 / 274);
  background: url('/art/card/vine-v.webp') center top / 100% auto repeat-y;
}
.card__vine--left {
  left: calc(var(--vine-line) - var(--vine) * 81 / 274);
  top: calc(var(--corner-inset) + var(--corner-w) * 0.732 - var(--overlap));
  bottom: calc(var(--corner-inset) + var(--corner-w) * 0.739 - var(--overlap));
}
.card__vine--right {
  right: calc(var(--vine-line) - var(--vine) * 81 / 274);
  top: calc(var(--corner-inset) + var(--corner-w) * 0.718 - var(--overlap));
  bottom: calc(var(--corner-inset) + var(--corner-w) * var(--br-down) - var(--overlap));
}

/* Ruled by hand, under the vine: four separate lines, each wandering a little, running just
   inside the vine's stem so the vine seems to grow along them. They start and end behind the
   corner clusters and fade there, so they never close into a box or show through the fruit.
   Each line's ends (--rule-a, --rule-b) are where its two corners' clusters end, in corner widths.
   (SVGs are given both sizes: an absolutely placed SVG otherwise takes its height from its
   viewBox's shape.) */
.card__rule {
  position: absolute;
  overflow: visible;
  pointer-events: none;
  mix-blend-mode: multiply;
  --rule-fade: calc(var(--corner-w) * 0.1);
  --rule-mask: linear-gradient(
    var(--rule-dir),
    transparent calc(var(--corner-w) * var(--rule-a)),
    #000 calc(var(--corner-w) * var(--rule-a) + var(--rule-fade)),
    #000 calc(100% - var(--corner-w) * var(--rule-b) - var(--rule-fade)),
    transparent calc(100% - var(--corner-w) * var(--rule-b))
  );
  -webkit-mask: var(--rule-mask);
  mask: var(--rule-mask);
}
.card__rule--top,
.card__rule--bottom {
  --rule-dir: to right;
  left: 0;
  width: 100%;
  height: 10px;
}
.card__rule--top {
  --rule-a: 0.62;
  --rule-b: 0.6;
  top: calc(var(--rule-inset) - 5px);
}
.card__rule--bottom {
  --rule-a: 0.62;
  --rule-b: var(--br-reach);
  bottom: calc(var(--rule-inset) - 5px);
}
.card__rule--left,
.card__rule--right {
  --rule-dir: to bottom;
  top: 0;
  height: 100%;
  width: 10px;
}
.card__rule--left {
  --rule-a: 0.55;
  --rule-b: 0.55;
  left: calc(var(--rule-inset) - 5px);
}
.card__rule--right {
  --rule-a: 0.55;
  --rule-b: var(--br-reach);
  right: calc(var(--rule-inset) - 5px);
}
.card__rule path {
  fill: none;
  stroke: var(--ink-soft);
  stroke-opacity: 0.55;
  stroke-width: 0.8px;
  vector-effect: non-scaling-stroke;
}

/* Printed type: inked into the paper rather than laid on top. The ink takes on the paper's
   texture and a faint speckle where it didn't take (the mask). */
.card__eyebrow,
.card__names,
.card__date,
.card__place,
.card__follow,
.card__calendar {
  position: relative;
  z-index: 2;
  margin: 0;
  mix-blend-mode: multiply;
  /* A picture of the grain, rendered once at 2x from textures/ink-grain.svg: the SVG itself is
     drawn by a filter, which would be recomputed for every line on every resize. */
  -webkit-mask: url('/textures/ink-grain.webp') 0 0 / 320px 320px;
  mask: url('/textures/ink-grain.webp') 0 0 / 320px 320px;
  -webkit-mask-clip: no-clip;
  mask-clip: no-clip;
}

/* SVG text can't take the grain mask (its letters drop out), so the arch is only multiplied. */
.card__arch {
  grid-area: arch;
  position: relative;
  z-index: 2;
  mix-blend-mode: multiply;
  width: 46cqi;
  overflow: visible;
}
.card__arch text {
  font: 500 15px var(--text);
  letter-spacing: 0.4em;
  fill: var(--ink);
}
.card__sprig {
  grid-area: sprig;
  position: relative;
  z-index: 2;
  /* As wide as the arched words, so the two read as one heading, cradled under the arch. */
  width: 31cqi;
  height: auto;
  margin-top: 1cqi;
}
.card__sprig--small {
  grid-area: divider;
  width: 22cqi;
  margin-top: 5cqi;
}
.card__eyebrow {
  grid-area: eyebrow;
  font: 500 3.4cqi var(--text);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  margin-top: 9cqi;
}

/* The names a little heavier and gently condensed, with sturdier hairlines than Bodoni's
   display size gives; the ampersand in italic, in lavender. */
.card__names {
  grid-area: names;
  display: grid;
  font: 600 20cqi / 0.92 var(--serif);
  font-variation-settings: 'opsz' 28;
  letter-spacing: -0.035em;
  margin-top: 4cqi;
}
.card__names span {
  white-space: nowrap;
  transform: scaleX(0.86);
}
.card__names em {
  font-style: italic;
  font-weight: 500;
  color: var(--amp);
  /* The italic is a separate font with taller ascenders; without this its line grows. */
  line-height: 0;
}

.card__photo {
  grid-area: photo;
  align-self: center;
  width: 90%;
  padding-block: 4.5cqi;
}
.card__photo .still-life__image {
  aspect-ratio: 4 / 3;
  --tilt: 0.6deg;
  --margin: 2.2cqi;
}

.card__date {
  grid-area: date;
  font: 600 4.6cqi var(--text);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.card__place {
  grid-area: place;
  font: 500 4cqi var(--text);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-top: 2.6cqi;
}
.card__follow {
  grid-area: follow;
  font: italic 400 4.6cqi var(--text);
  letter-spacing: 0.03em;
  color: var(--ink-soft);
  margin-top: 3cqi;
}
.card__calendar {
  grid-area: calendar;
  font: 400 3.3cqi var(--text);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #7a5470;
  text-decoration: none;
  border-bottom: 0.5px solid #7a547066;
  padding: 2cqi 0 0.5cqi;
  margin-top: 2cqi;
}

/* Side by side on wide screens: the words on the left, the photo on the right, on a landscape
   card a little squarer than a 7 × 5. Wide means 960px, or 700px in a clearly landscape window;
   that also keeps browser zoom from dropping a laptop to the smaller stacked card. The words'
   column centres on the card's height, and the padding keeps everything clear of the corners. */
@media (min-width: 960px) and (min-aspect-ratio: 4/5),
  (min-width: 700px) and (min-aspect-ratio: 5/4),
  (pointer: coarse) and (min-width: 520px) and (min-aspect-ratio: 4/5) {
  .card {
    --width: min(
      100vw - 2 * var(--margin),
      max((100svh - 2 * var(--margin)) * 1.36, var(--zoom-floor)),
      1120px
    );
    --corner-share: 0.19;
    min-height: 0;
    aspect-ratio: 1.36;
    padding: calc(var(--width) * 0.105) calc(var(--width) * 0.095);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: 1fr repeat(9, auto) 1fr;
    grid-template-areas:
      '. photo'
      'arch photo'
      'sprig photo'
      'eyebrow photo'
      'names photo'
      'date photo'
      'place photo'
      'divider photo'
      'follow photo'
      'calendar photo'
      '. photo';
    column-gap: 6cqi;
    /* The feature corner, the pomegranate and mandarin: a wider piece, sized so its mandarin
       matches the other corners' fruit (measured: 1.24 times their width). */
    --corner-br-w: calc(var(--corner-w) * 1.24);
    --br-across: 1.287;
    --br-down: 0.829;
    --br-reach: 0.95;
  }
  .card__corner--feature {
    width: var(--corner-br-w);
    bottom: calc(var(--corner-inset) + var(--corner-w) * 0.044);
    right: calc(var(--corner-inset) + var(--corner-w) * 0.0645);
  }
  .card__arch {
    width: 25cqi;
  }
  .card__sprig {
    width: 16.2cqi;
    margin-top: -1.3cqi;
  }
  .card__sprig--small {
    width: 11cqi;
    margin-top: 2.2cqi;
  }
  .card__eyebrow {
    font-size: 1.55cqi;
    margin-top: 4.9cqi;
  }
  .card__names {
    font-size: 9.6cqi;
    margin-top: 2.4cqi;
  }
  /* Portrait in its column, centred on the card's height. */
  .card__photo {
    width: min(100%, 50cqi);
    padding-block: 0;
  }
  .card__photo .still-life__image {
    aspect-ratio: 4 / 5;
    --margin: 1.1cqi;
  }
  .card__photo .still-life__photo {
    object-position: 38% 50%;
  }
  .card__date {
    font-size: 2.15cqi;
    margin-top: 3.2cqi;
  }
  .card__place {
    font-size: 1.65cqi;
    margin-top: 1.1cqi;
  }
  .card__follow {
    font-size: 1.9cqi;
    margin-top: 1.4cqi;
  }
  .card__calendar {
    font-size: 1.4cqi;
    padding-top: 0.9cqi;
    margin-top: 0.8cqi;
  }
}

/* Hidden for the moment between first paint and the fonts arriving (see card-early.js). */
.card-pending [data-card] {
  visibility: hidden;
}

/* First arrival of a session, like a card being laid down and then drawn: the card settles on
   the cloth, the corner fruit appears, the vine grows out from the corners along each edge, the
   sprigs open out from their blossoms, and the words ink in. Every step is a clip or a fade, so
   it stays smooth in every browser. */
@keyframes card-settle {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}
@keyframes card-ink {
  from {
    opacity: 0;
  }
}
@keyframes card-bloom {
  from {
    clip-path: circle(0% at var(--from));
  }
  to {
    clip-path: circle(150% at var(--from));
  }
}
@keyframes card-grow-across {
  from {
    clip-path: inset(-10% 100% -10% 0);
  }
  to {
    clip-path: inset(-10% 0 -10% 0);
  }
}
@keyframes card-grow-down {
  from {
    clip-path: inset(0 -10% 100% -10%);
  }
  to {
    clip-path: inset(0 -10% 0 -10%);
  }
}
@keyframes card-open {
  from {
    clip-path: inset(0 50% 0 50%);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}
.card-arriving .card {
  animation: card-settle 0.8s cubic-bezier(0.2, 0.7, 0.25, 1) both;
}
.card-arriving .card__corner {
  animation: card-bloom 0.9s cubic-bezier(0.3, 0.6, 0.3, 1) 0.3s both;
}
.card-arriving .card__corner--tl {
  --from: 15% 15%;
}
.card-arriving .card__corner--tr {
  --from: 85% 15%;
}
.card-arriving .card__corner--bl {
  --from: 15% 85%;
}
.card-arriving .card__corner--br {
  --from: 85% 85%;
}
.card-arriving :is(.card__vine--top, .card__vine--bottom, .card__rule--top, .card__rule--bottom) {
  animation: card-grow-across 1.5s cubic-bezier(0.4, 0.1, 0.3, 1) 0.6s both;
}
.card-arriving :is(.card__vine--left, .card__vine--right, .card__rule--left, .card__rule--right) {
  animation: card-grow-down 1.5s cubic-bezier(0.4, 0.1, 0.3, 1) 0.6s both;
}
.card-arriving .card__sprig {
  animation: card-open 0.9s cubic-bezier(0.3, 0.6, 0.3, 1) 1s both;
}
.card-arriving .card > :is(p, h1, .card__arch, .card__photo, .card__calendar) {
  animation: card-ink 1s ease 0.4s both;
}
.card-arriving .card__names {
  animation-delay: 0.55s;
}
.card-arriving .card__photo {
  animation-delay: 0.75s;
}
@media (prefers-reduced-motion: reduce) {
  .card-arriving :is(.card, .card *) {
    animation: none !important;
  }
}

/* Printing: the card alone, as large as the page allows, on plain paper (the real paper is the
   paper, so no shadow, no cloth; a calendar link means nothing on paper). */
@media print {
  .site-main.site-main--home {
    --margin: 0px;
    min-height: 100vh;
    padding: 0;
  }
  .card {
    --width: min(100vw, 100vh / var(--tall));
    min-height: min(100vh, 2 * var(--width));
    break-inside: avoid;
  }
  .card::after,
  .card__calendar {
    display: none;
  }
  /* The real paper is the paper: no printed texture or deckle. */
  .card::before {
    background: none;
    -webkit-mask: none;
    mask: none;
  }
  .card-arriving :is(.card, .card *) {
    animation: none !important;
  }
}
/* Printed on a landscape page, the card is side by side (the same layout as wide screens). */
@media print and (min-width: 960px) and (min-aspect-ratio: 4/5) {
  .card {
    --width: min(100vw, 100vh * 1.36);
    min-height: 0;
  }
}
