/* ===== The wedding invitation =====
 *
 * WHY THIS IS ITS OWN FILE, AND NOT MORE OF css/envelope.css
 *
 * The same reason css/samples.css gives at the top of itself: /css/* is served
 * with max-age=31536000 and the filenames are NOT fingerprinted (_headers:364).
 * A structural change appended to envelope.css would be invisible for up to a
 * year to every browser that already holds a copy of it — and a wedding card
 * half-restyled is worse than one not restyled at all, because the two halves
 * disagree about where the gold is. A NEW filename is a cache miss by
 * construction, so this arrives whole or not at all.
 *
 * WHAT IT IS FOR
 *
 * A wedding invitation is not a greeting card with a different palette on it.
 * Three sources agree on the same formula, and none of them is optional:
 * a full-perimeter ornamental frame; an invocation mark at the top; and GOLD as
 * the metal that ties the frame, the mark and the couple's names together. The
 * product already had the artefact and the invocation. This adds the frame and
 * the gold.
 *
 * HOW IT COMPOSES WITH THE CRAFT PANEL
 *
 * Every selector here is prefixed .theme-wedding, so nineteen other occasions
 * are byte-for-byte what they were. Inside the wedding, the rule is that the
 * SENDER still wins:
 *   - Colour comes through the same variables the craft panel writes INLINE on
 *     the theme root (--paper, --env-*, --seal, --accent). Inline beats a class,
 *     so a sender who picks Sage envelope stock or Navy wax gets it, exactly as
 *     on every other occasion. Nothing here hardcodes a value the panel owns.
 *   - The gold frame on the sheet draws only when the sender has NOT chosen a
 *     border (see section 6), because 'none' is the default and means "no
 *     opinion", not "no frame". Deckle, Ruled and Double still replace it.
 * Gold itself is not a craft option and is not treated as one: it is the
 * wedding's metal the way wax is the product's material.
 *
 * CONTRAST
 *
 * The couple's names are the most important line on the card, and a foil
 * gradient is the easiest way to make a name illegible — the light band of a
 * convincing foil is around 1.1:1 on ivory paper. Every stop in --foil is
 * therefore held at 3:1 or better against the paper (section 9 lists them). The
 * foil is less showy than it could be. That is the trade, taken deliberately:
 * nobody's name disappears into the shine.
 */

/* ---------- 1. Tokens ----------
   The alpha variants are spelled out rather than derived, because rgba() cannot
   take a hex custom property as its colour and color-mix() is younger than the
   Android WebViews this product still sees. Three names, one place to change. */
.card-theme.theme-wedding {
    --gold-deep: #8a6a24;
    --gold: #b98f3d;
    --gold-pale: #f6ecd0;

    --gold-line: rgba(138,106,36,.55);   /* a drawn hairline */
    --gold-line-soft: rgba(138,106,36,.34);
    --gold-veil: rgba(138,106,36,.22);   /* a shadow of one */

    /* ---- The foil ----
       Seven stops, and every one of them is between 3.30:1 and 4.84:1 on the
       #fffaf0 paper below, so no part of a name drops under the 3:1 that
       large text needs. A real foil swings to near-white; this one is not
       allowed to, for the reason in the header. */
    --foil: linear-gradient(102deg,
        #8f6a25 0%,   /* 4.74 */
        #a87f30 20%,  /* 3.51 */
        #ad8433 34%,  /* 3.30 */
        #9a722a 50%,  /* 4.19 */
        #8f6a25 68%,  /* 4.74 */
        #a87f30 88%,  /* 3.51 */
        #8a6a24 100%  /* 4.84 */
    );

    /* Ivory rag rather than the site's #fbf7f2, which is a letter-writing
       paper. Set as --paper and not on .letter, so the four craft papers still
       override it inline and so .border-double's box-shadow (which reads
       --paper to punch its gap) stays correct. */
    --paper: #fffaf0;

    /* Ivory-and-gold envelope stock, replacing the pink. The pink envelope was
       the single strongest reason the card read as a greeting card. Still just
       the same three variables the craft panel writes, so "Blush" brings the
       pink back for a sender who wants it. */
    --env-1: #f6ddc6; --env-2: #e6bf9a; --env-3: #cfa273;

    /* --bg-2 deepens from #f3d2e2 so the card is not pink paper on pink air.
       --accent, --seal and --seal-2 are deliberately NOT touched: the analysis
       above .card-theme.theme-wedding in css/envelope.css derives this tile's
       #a12b63 from a deltaE separation against love and diwali and from the
       white seal glyph's contrast, and nudging the crimson two units for no
       reason would make all of that quietly untrue. */
    --bg-2: #d9a8bf;

    /* The event leaves stand taller than a message sheet needs to, because an
       event is four short lines that should sit in the middle of a page rather
       than at the top of one. Read by .packet-leaf in section 11. */
    --leaf-h: calc(var(--card-enclosed-maxh) * .78);
}

/* ---------- 2. The ground, and why it is left alone on a phone ----------
   There is deliberately no .theme-wedding.card-page rule here, only the
   deepened --bg-2 above and the desktop treatment in section 15.
   A warm gold pool under the card was tried and removed. It survives on desktop
   (section 15) because there the card is a small object in a large field and the
   pool gives the stage a middle. On a phone it does the opposite: the card fills
   the width, so the pool is completely hidden the moment the envelope opens, and
   before it opens the envelope sits higher than the pool does — which leaves a
   soft brown ellipse alone on the pink, reading as a stain on the page rather
   than as light behind the card. Verified in the sealed state at 390px, which is
   the one state on the one width where nothing covers it. */

/* ---------- 3. The envelope ----------
   A gold hairline along every fold, with NO new DOM — the recipient page's
   markup is shared with the craft preview, the hero and the mini stage, and a
   new element would have to be added in five places and then explained in all
   of them.
   The trick: the PANEL becomes solid gold, and its ::after carries the real
   envelope gradient clipped to a slightly SMALLER triangle. Gold survives only
   in the 2-3px band between the two outlines, which is exactly where the fold
   is. ::after on all four is free — css/envelope.css uses none of them (it
   takes .env-body::after, which is left alone). */
.theme-wedding .env-left,
.theme-wedding .env-right,
.theme-wedding .env-bottom,
.theme-wedding .env-flap-face {
    background: rgba(138,106,36,.62);
}

.theme-wedding .env-left::after,
.theme-wedding .env-right::after,
.theme-wedding .env-bottom::after,
.theme-wedding .env-flap-face::after {
    content: '';
    position: absolute;
    inset: 0;
}

/* Each clip-path is the panel's own triangle pulled in by 2-3px. The apex needs
   the larger inset because a point converges faster than an edge: at 2px the
   gold pinched out to nothing exactly where the three folds meet, which is the
   one place on the envelope the eye checks for craftsmanship. */
.theme-wedding .env-left::after {
    clip-path: polygon(0 2px, calc(100% - 3px) 50%, 0 calc(100% - 2px));
    background:
        linear-gradient(100deg, rgba(255,255,255,.30), rgba(255,255,255,.04)),
        linear-gradient(120deg, var(--env-1), var(--env-2) 70%, var(--env-3));
}

.theme-wedding .env-right::after {
    clip-path: polygon(100% 2px, 3px 50%, 100% calc(100% - 2px));
    background:
        linear-gradient(-100deg, rgba(255,255,255,.22), rgba(255,255,255,.02)),
        linear-gradient(-120deg, var(--env-1), var(--env-2) 70%, var(--env-3));
}

.theme-wedding .env-bottom::after {
    clip-path: polygon(2px calc(100% - 1px), 50% 3px, calc(100% - 2px) calc(100% - 1px));
    background: linear-gradient(180deg, var(--env-2), var(--env-3));
}

.theme-wedding .env-flap-face::after {
    clip-path: polygon(2px 2px, calc(100% - 2px) 2px, 50% calc(100% - 3px));
    background: linear-gradient(175deg, var(--env-1), var(--env-2) 85%);
}

/* An inner gold frame on the envelope's own face, inside the folds. ::before is
   free here; css/envelope.css:326 has taken ::after. Inside .env-body's own
   stacking context (it is position + z-index: 1), so this cannot climb above
   the front panels or the card — it frames the envelope's inner face, which is
   what a lined wedding envelope has. */
.theme-wedding .env-body::before {
    content: '';
    position: absolute;
    inset: 7px;
    border-radius: 3px;
    border: 1px solid var(--gold-line);
    box-shadow: inset 0 0 0 3px rgba(255,255,255,.28),
                inset 0 0 0 4px var(--gold-veil);
    z-index: 2;
}

/* ---------- 4. The wax ----------
   Wax does not set in a circle. An irregular border-radius plus a conic grain
   turns a disc into a poured blob. The colour is still --seal, so all six wax
   choices work; only the SHAPE is the wedding's. ::before carries the ring
   behind the seal (css/envelope.css:1142) and has to be given the same outline,
   or a round shadow shows behind an irregular seal. */
.theme-wedding .seal {
    border-radius: 48% 52% 47% 53% / 53% 47% 52% 48%;
    background:
        radial-gradient(circle at 34% 26%, rgba(255,255,255,.45), transparent 44%),
        repeating-conic-gradient(from 0deg at 50% 50%,
            rgba(255,255,255,.05) 0 4deg, rgba(0,0,0,.05) 4deg 8deg),
        radial-gradient(circle at 68% 78%, var(--seal-2), transparent 58%),
        var(--seal);
}

.theme-wedding .seal::before {
    border-radius: 48% 52% 47% 53% / 53% 47% 52% 48%;
}

/* ---------- 5. The invitation sheet ----------
   Four gold corner ornaments and a woven ground.
   background-image ONLY, as a longhand: .letter's own `background: var(--paper)`
   is a shorthand, so declaring the image list here composes with it rather than
   replacing the paper — which is what keeps the four craft papers working. The
   padding is deliberately not restated; it is 26px 24px 22px in
   css/envelope.css and the ornaments are positioned to sit inside it.
   One SVG, rotated four ways by transform inside the data URL, so there is one
   drawing to maintain and the browser caches it once. */
.theme-wedding .letter {
    background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, repeat;
    background-size: 30px 30px, 30px 30px, 30px 30px, 30px 30px, auto;
    background-position:
        left 9px top 9px, right 9px top 9px,
        right 9px bottom 9px, left 9px bottom 9px, 0 0;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cg fill='none' stroke='%238a6a24' stroke-width='1' stroke-linecap='round'%3E%3Cpath d='M1 12V4a3 3 0 0 1 3-3h8'/%3E%3Cpath d='M4.5 18C4.5 10.5 10.5 4.5 18 4.5'/%3E%3C/g%3E%3Cpath fill='%23b98f3d' d='M6.6 8.4c1.5-1.9 3.6-2 3.6-2s-.1 2.1-2 3.6c-1.3 1-2.5.7-2.5.7s-.2-1.1.9-2.3z'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cg transform='translate(30,0) scale(-1,1)'%3E%3Cg fill='none' stroke='%238a6a24' stroke-width='1' stroke-linecap='round'%3E%3Cpath d='M1 12V4a3 3 0 0 1 3-3h8'/%3E%3Cpath d='M4.5 18C4.5 10.5 10.5 4.5 18 4.5'/%3E%3C/g%3E%3Cpath fill='%23b98f3d' d='M6.6 8.4c1.5-1.9 3.6-2 3.6-2s-.1 2.1-2 3.6c-1.3 1-2.5.7-2.5.7s-.2-1.1.9-2.3z'/%3E%3C/g%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cg transform='translate(30,30) scale(-1,-1)'%3E%3Cg fill='none' stroke='%238a6a24' stroke-width='1' stroke-linecap='round'%3E%3Cpath d='M1 12V4a3 3 0 0 1 3-3h8'/%3E%3Cpath d='M4.5 18C4.5 10.5 10.5 4.5 18 4.5'/%3E%3C/g%3E%3Cpath fill='%23b98f3d' d='M6.6 8.4c1.5-1.9 3.6-2 3.6-2s-.1 2.1-2 3.6c-1.3 1-2.5.7-2.5.7s-.2-1.1.9-2.3z'/%3E%3C/g%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cg transform='translate(0,30) scale(1,-1)'%3E%3Cg fill='none' stroke='%238a6a24' stroke-width='1' stroke-linecap='round'%3E%3Cpath d='M1 12V4a3 3 0 0 1 3-3h8'/%3E%3Cpath d='M4.5 18C4.5 10.5 10.5 4.5 18 4.5'/%3E%3C/g%3E%3Cpath fill='%23b98f3d' d='M6.6 8.4c1.5-1.9 3.6-2 3.6-2s-.1 2.1-2 3.6c-1.3 1-2.5.7-2.5.7s-.2-1.1.9-2.3z'/%3E%3C/g%3E%3C/svg%3E"),
        repeating-linear-gradient(90deg, rgba(154,116,41,.045) 0 1px, transparent 1px 4px);
}

/* ---------- 6. The gold frame, and only as a default ----------
   .letter::after is where the craft panel's border flourish draws
   (css/envelope.css:1175 and the four rules under it). This claims it ONLY when
   the sender has left the border alone.
   The test is written as three :not()s rather than as .border-none, because
   js/craft.js:281 never adds a border-none class — 'none' is the absence of one.
   So this matches the default and loses to any explicit choice, which is the
   right way round: a gold frame is what a wedding invitation has when nobody
   said otherwise, and Deckle is what it has when somebody did.
   var(--paper) in the box-shadow, exactly as .border-double does, so the gap
   between the two gold lines is the paper's colour and not a hardcoded ivory
   sitting on a sender's Mist. */
.theme-wedding:not(.border-deckle):not(.border-ruled):not(.border-double) .letter::after {
    inset: 7px;
    border: 1px solid rgba(138,106,36,.42);
    box-shadow: 0 0 0 3px var(--paper), 0 0 0 4px rgba(138,106,36,.20);
    border-radius: 2px;
}

/* ---------- 7. The invocation, in a gold roundel ----------
   The mark was already there and already right; it was floating. A struck
   roundel is what an invocation sits in on a printed invitation, and it is the
   first gold the eye meets. opacity: 1 because .letter-mark is dimmed by
   default, and a devotional mark is not a decorative one. */
.theme-wedding .letter-mark.is-invocation {
    width: 52px;
    height: 52px;
    padding: 9px;
    margin-bottom: 12px;
    color: var(--gold-deep);
    opacity: 1;
    border-radius: 50%;
    background: radial-gradient(circle at 42% 34%, #fffdf6, var(--gold-pale) 62%, #e6d2a4 100%);
    /* Ring, paper gap, outer ring, then a shadow: the four steps that make a
        disc look pressed into the sheet rather than laid on it. */
    box-shadow: 0 0 0 1px var(--gold-line),
                0 0 0 4px var(--paper),
                0 0 0 5px rgba(138,106,36,.28),
                0 2px 6px rgba(120,86,20,.18);
}

/* ---------- 8. The transliteration ----------
   Hairlines either side, which is how a printed invitation sets a line of
   Sanskrit in roman. #8a6a24 on the #fffaf0 paper is 4.84:1, which clears AA.

   .74rem, which is css/envelope.css:2328's own size, and NOT the .6rem this was
   first written at. Measured at 320px: "Shree Ganeshaya Namah" with a nowrap
   line and a fixed 26px rule either side overflowed the sheet by 17px at EVERY
   size down to .6rem, so the small size never bought the fit it was there for —
   it just made the overflow smaller while dropping the type to 9.6px, on a card
   whose reported problem was text too small to read.

   Three declarations do the fitting instead, and each covers a width the others
   do not:
     - letter-spacing .12em rather than .18em: at .74rem the tracking was worth
       about 20px of line, which is the difference between one line and two on a
       tablet.
     - flex: 0 1 26px on the rules: they are allowed to give now. A frame that
       shrinks is better than text that is clipped, which is what 0 0 26px meant.
     - white-space: normal: the last resort. If a longer invocation ever arrives
       it wraps instead of running off the paper.
   And on a phone the rules go entirely — see the block at the end of section 8.
   72px of hairline and gap out of 199px of usable width was the real problem at
   320px, and a plain centred line at full size is both the larger type and the
   cleaner setting. */
.theme-wedding .letter-invoke {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    flex-wrap: nowrap;
    white-space: normal;
    font-size: .74rem;
    letter-spacing: .12em;
    color: var(--gold-deep);
    margin-bottom: 16px;
}

.theme-wedding .letter-invoke::before,
.theme-wedding .letter-invoke::after {
    content: '';
    height: 1px;
    width: 26px;
    flex: 0 1 26px;
    background: linear-gradient(90deg, transparent, rgba(138,106,36,.75));
}

.theme-wedding .letter-invoke::after {
    background: linear-gradient(270deg, transparent, rgba(138,106,36,.75));
}

/* On a phone the transliteration stands alone. Verified at 320px: with the rules
   it wraps to two lines at any size that is worth reading; without them it is one
   line of .74rem with room to spare. The mark above it and the couple below it
   already frame it, which is the job the hairlines were doing. */
@media (max-width: 420px) {
    .theme-wedding .letter-invoke::before,
    .theme-wedding .letter-invoke::after { display: none; }
}

/* ---------- 9. The couple, in foil ----------
   background-clip: text is what turns the gradient into the letterforms.
   The plain `color` is declared FIRST and outside the @supports, so a browser
   that cannot clip a background to text still prints the names in dark gold at
   4.84:1. -webkit-text-fill-color: transparent is the declaration that would
   erase them if the clip silently failed, so it is the one gated behind the
   feature query — the failure mode of this effect is an invisible name, and
   that is not a failure this card is allowed to have. */
.theme-wedding .letter-couple {
    font-size: 1.72rem;
    letter-spacing: .005em;
    margin-bottom: 6px;
    color: var(--gold-deep);
    /* Two names and an ampersand should break into two balanced lines, not one
       long line and a widowed name. */
    text-wrap: balance;
}

@supports ((background-clip: text) or (-webkit-background-clip: text)) {
    .theme-wedding .letter-couple {
        background: var(--foil);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
    }
}

/* ---------- 10. The rule ----------
   A gold hairline with a lozenge struck through the middle of it, which is the
   divider a printed invitation uses between the names and the details. The
   lozenge is a rotated square on ::after; .letter-rule has no pseudo-elements
   in css/envelope.css. */
.theme-wedding .letter-rule {
    position: relative;
    width: 96px;
    height: 1px;
    opacity: 1;
    background: linear-gradient(90deg,
        transparent, rgba(138,106,36,.6) 22%, rgba(138,106,36,.6) 78%, transparent);
    margin: 0 auto 16px;
}

.theme-wedding .letter-rule::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 5px;
    height: 5px;
    /* Half of 5px, negated: centring a 5px box on a 1px line, where transform is
       already spoken for by the rotation. */
    margin: -2.5px 0 0 -2.5px;
    background: var(--gold);
    transform: rotate(45deg);
}

/* ---------- 11. The event leaves ----------
   Each function in the packet gets a page rather than a caption. Centred and
   framed, because four short lines pinned to the top of a tall sheet reads as
   an unfinished page.
   Colours: the label takes --accent, so the sender's wax choice tints the
   function names the same way it tints the letter mark and the signature on
   every other occasion. */
.theme-wedding .packet-leaf {
    min-height: var(--leaf-h);
    justify-content: center;
    padding: 26px 22px;
    background-color: var(--paper);
    box-shadow: 0 2px 9px rgba(60,30,40,.15),
                inset 0 0 0 1px var(--gold-veil);
}

.theme-wedding .packet-leaf::before {
    content: '';
    position: absolute;
    inset: 8px;
    border-radius: 2px;
    border: 1px solid var(--gold-line-soft);
    /* The frame must never be the thing a tap lands on: the leaves are swiped
       and the dots are tapped. */
    pointer-events: none;
}

.theme-wedding .leaf-label {
    font-size: 1.34rem;
    color: var(--accent);
    letter-spacing: .02em;
    margin-bottom: 10px;
}

.theme-wedding .leaf-when {
    font-size: 1rem;
    letter-spacing: .03em;
    color: var(--gold-deep);
    margin-bottom: 12px;
}

.theme-wedding .leaf-where {
    font-size: .98rem;
    color: var(--ink);
}

/* #6f6058 and not the prototype's #9a8b83: that was 3.16:1 on this paper, and
   this is small uppercase text, which needs 4.5. This is 5.78:1 and still reads
   as the quietest line on the page.
   .82rem and not the prototype's .76rem either. css/envelope.css:2275 sets this
   line at .88rem in lower case; uppercase letterforms read about a third larger
   at the same size, so .82rem uppercase is already the larger of the two on the
   page while staying clearly subordinate to the .98rem venue above it. Going
   down to .76rem would have made the city the one line on this card that got
   SMALLER than every other occasion's — and the feedback that started this work
   was that the text on the card was too small to read. */
.theme-wedding .leaf-city {
    font-size: .82rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: #6f6058;
    margin-top: 6px;
}

/* ---------- 12. The sheet behind an open leaf ----------
   css/envelope.css:2094 hides the sheet's own contents while a leaf is open, so
   what shows around the insert is bare paper. A watermark makes that a lined
   envelope's interior instead of a void.
   NOT overflow: hidden and NOT max-height here, either of which clips the
   insert that is standing on top of this sheet. */
.theme-wedding .letter.leaf-open {
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%238a6a24' opacity='.16'%3E%3Cpath d='M12 3c1 .6 1.6 1.5 1.6 2.6 0 1.2-.7 2.1-1.6 2.6-1-.5-1.6-1.4-1.6-2.6C10.4 4.5 11 3.6 12 3z'/%3E%3Cpath d='M18.5 6.4c.2 1.1-.2 2.2-1.1 2.9-1 .7-2.2.7-3.1.2.2-1.1.9-2 1.9-2.5.9-.5 1.7-.6 2.3-.6z'/%3E%3Cpath d='M5.5 6.4c-.2 1.1.2 2.2 1.1 2.9 1 .7 2.2.7 3.1.2-.2-1.1-.9-2-1.9-2.5-.9-.5-1.7-.6-2.3-.6z'/%3E%3Cpath d='M12 9.6c2.9 0 5.2 1.9 5.2 4.2S14.9 18 12 18s-5.2-1.9-5.2-4.2S9.1 9.6 12 9.6z'/%3E%3C/svg%3E"),
        repeating-linear-gradient(90deg, rgba(154,116,41,.045) 0 1px, transparent 1px 4px);
    background-repeat: no-repeat, repeat;
    background-size: 112px 112px, auto;
    background-position: center 82%, 0 0;
}

/* ---------- 13. The packet dots ----------
   background-color and NOT the background shorthand: css/envelope.css builds
   these dots with a shorthand of its own and a shorthand here would drop the
   rest of it.
   The first dot is the invitation itself rather than an event, and it is the one
   a reader needs to find again after paging through four functions — so it is a
   diamond among circles, which is findable without colour. */
.theme-wedding .packet-dot {
    background-color: var(--gold-deep);
    opacity: .55;
}

.theme-wedding .packet-dot.is-on {
    opacity: 1;
    background-color: var(--accent);
}

.theme-wedding .packet-dot:first-child {
    border-radius: 2px;
    transform: rotate(45deg);
}

/* The rotation has to be restated: `transform` is one property, and the scale
   that marks the current dot would otherwise replace the rotation and turn the
   diamond back into a square. */
.theme-wedding .packet-dot:first-child.is-on {
    transform: rotate(45deg) scale(1.28);
}

/* ---------- 14. The one thing the deeper ground broke ----------
   "Want to send one back?" above the CTA is #7d6b64 (css/envelope.css:3284),
   which was 3.64:1 on the old #f3d2e2 and is 2.48:1 on the deepened --bg-2 —
   a fail, on the line js/card.js:236 calls the only way this product grows.
   #4a2f3a is 5.86:1 against --bg-2 and 5.26:1 against the desktop gradient's
   darkest stop in section 15, so it clears AA at both ends of the field.
   The button beside it needs nothing: .btn-ghost sits on a 55%-white wash, and
   --accent over that wash is unchanged from every other occasion. */
.theme-wedding .after-reveal p {
    color: #4a2f3a;
}

/* ---------- 15. Desktop ----------
   On a wide screen the card was a small object in a large flat field. A lit
   surface under it and a vignette around the edges give the stage a middle,
   which is the difference between a card on a table and a card in a void. */
@media (min-width: 900px) {
    .theme-wedding.card-page {
        background:
            radial-gradient(ellipse 34% 30% at 50% 52%, rgba(255,251,240,.85), rgba(255,251,240,0) 70%),
            radial-gradient(ellipse 58% 46% at 50% 50%, rgba(185,143,61,.20), rgba(185,143,61,0) 72%),
            radial-gradient(ellipse 120% 90% at 50% 50%, rgba(78,20,45,0) 42%, rgba(78,20,45,.30) 100%),
            linear-gradient(170deg, #f3cddd, #d59cb6);
    }
}

/* ---------- 16. The three small envelopes ----------
   Everything above is written for a card someone is holding. Three places draw
   the same markup at about a sixth of the area instead: the landing page's hero
   mock, the sender's mini-stage on preview.html, and the live preview beside the
   craft panel on create.html. css/envelope.css:2311 and :2374 already size the
   mark and the packet down for those, and this file is loaded after it — so
   without this section a 52px roundel and a 1.34rem function name land inside a
   165px-wide mock and the invitation becomes an unreadable blur of gold.

   Specificity, not order. css/envelope.css:2299 states the rule this section
   obeys: "a rule that only wins by coming later stops winning the day someone
   reorders the file." Each selector below adds .theme-wedding to the context, so
   it carries one class more than the base rule it is narrowing and would still
   win if this file were moved above envelope.css tomorrow.

   Two selector shapes, because the theme class does not sit in the same place in
   all three. On index.html and create.html it is on the mock's own element
   (`hero-demo card-theme theme-wedding`; refreshCraftPreview() writes
   `craft-phone card-theme env-static ` + card.theme), so those are compound. On
   preview.html js/preview.js:368 puts it on <body>, an ancestor of .mini-stage,
   so that one is a descendant selector. The verify script asserts these really
   match, because a dead selector here fails silently and looks fine.

   .theme-wedding.hero-demo matches nothing today, and that is recorded rather
   than removed. DEMO_CARD is hardcoded type: 'love' (js/main.js:145) and
   applyCraft() does not put an occasion class on the wrapper at all — #demoWrap
   stays `hero-demo card-theme`. So the landing page cannot currently show a
   wedding, and css/envelope.css:2311's own .hero-demo rules are equally
   defensive. Kept because the day the hero does cycle occasions, the mock would
   otherwise get the full-size roundel; whoever does that will also have to add
   the theme class, without which none of this file reaches the hero at all.

   The numbers track css/envelope.css's mock scale rather than being derived
   again from the desktop values, so the wedding leaf sits at the same size as
   every other occasion's leaf in the same mock — which is the point of a mock. */
.theme-wedding.hero-demo .letter-mark.is-invocation,
.theme-wedding .mini-stage .letter-mark.is-invocation,
.theme-wedding.craft-phone .letter-mark.is-invocation {
    width: 26px;
    height: 26px;
    padding: 3px;
    margin-bottom: 5px;
    /* The four-step shadow becomes three: at 26px the 4px paper gap and the 5px
       outer ring together are wider than the disc's own radius, so they stop
       reading as a pressed roundel and start reading as a smudge. The drop
       shadow goes too — it is 2px of blur on a 26px object. */
    box-shadow: 0 0 0 1px var(--gold-line),
                0 0 0 2px var(--paper),
                0 0 0 3px rgba(138,106,36,.28);
}

/* The transliteration has no mock size of its own in css/envelope.css, so it
   inherits the real card's .74rem — which in a 165px sheet is most of the width
   before the hairlines are counted. The rules come down with it, and stay
   shrinkable (0 1, not 0 0) for the same reason they are shrinkable at full
   size: a frame that gives is better than text that is clipped. */
.theme-wedding.hero-demo .letter-invoke,
.theme-wedding .mini-stage .letter-invoke,
.theme-wedding.craft-phone .letter-invoke {
    font-size: .46rem;
    letter-spacing: .12em;
    gap: 5px;
    margin-bottom: 7px;
}

.theme-wedding.hero-demo .letter-invoke::before,
.theme-wedding .mini-stage .letter-invoke::before,
.theme-wedding.craft-phone .letter-invoke::before,
.theme-wedding.hero-demo .letter-invoke::after,
.theme-wedding .mini-stage .letter-invoke::after,
.theme-wedding.craft-phone .letter-invoke::after {
    width: 11px;
    flex: 0 1 11px;
}

.theme-wedding.hero-demo .letter-couple,
.theme-wedding .mini-stage .letter-couple,
.theme-wedding.craft-phone .letter-couple {
    font-size: .82rem;
    margin-bottom: 3px;
}

.theme-wedding.hero-demo .letter-rule,
.theme-wedding .mini-stage .letter-rule,
.theme-wedding.craft-phone .letter-rule {
    width: 42px;
    margin-bottom: 7px;
}

/* The lozenge is dropped rather than scaled: a 5px diamond on a 42px rule is
   a twelfth of its length, and below about 3px a rotated square renders as a
   grey pixel with no diagonal in it. The rule alone is the cleaner mock. */
.theme-wedding.hero-demo .letter-rule::after,
.theme-wedding .mini-stage .letter-rule::after,
.theme-wedding.craft-phone .letter-rule::after {
    display: none;
}

/* min-height goes back to 0. --leaf-h is 78% of --card-enclosed-maxh, which the
   mocks do scale, but the mock leaf is short enough that centring inside it
   changes nothing and a floor here only risks the leaf outgrowing the card. */
.theme-wedding.hero-demo .packet-leaf,
.theme-wedding .mini-stage .packet-leaf,
.theme-wedding.craft-phone .packet-leaf {
    min-height: 0;
    padding: 13px 11px 12px;
}

/* inset: 8px on a leaf with 13px/11px of padding would leave 3px between the
   frame and the label. 4px keeps the same proportion the real leaf has. */
.theme-wedding.hero-demo .packet-leaf::before,
.theme-wedding .mini-stage .packet-leaf::before,
.theme-wedding.craft-phone .packet-leaf::before {
    inset: 4px;
}

.theme-wedding.hero-demo .leaf-label,
.theme-wedding .mini-stage .leaf-label,
.theme-wedding.craft-phone .leaf-label { font-size: .78rem; margin-bottom: 5px; }

.theme-wedding.hero-demo .leaf-when,
.theme-wedding .mini-stage .leaf-when,
.theme-wedding.craft-phone .leaf-when { font-size: .66rem; margin-bottom: 4px; }

.theme-wedding.hero-demo .leaf-where,
.theme-wedding .mini-stage .leaf-where,
.theme-wedding.craft-phone .leaf-where { font-size: .66rem; }

.theme-wedding.hero-demo .leaf-city,
.theme-wedding .mini-stage .leaf-city,
.theme-wedding.craft-phone .leaf-city { font-size: .56rem; letter-spacing: .1em; }
