
html,body,footer {
    max-width: 100%;
    overflow-x: clip;
}

/* Long unbroken strings — a URL, a hashtag, or simply someone typing without
   spaces — have no break opportunity, so the browser lets them run straight out
   of their column and over the neighbouring content. That was visible in the
   Programme timeline and the Notre Histoire paragraphs. `break-word` only kicks
   in for words that cannot otherwise fit, so ordinary copy still wraps at
   spaces exactly as before.
   This is a fix to the site itself, not to the editor: the same overflow could
   always have been produced by editing the template. */
p,
h2,
h3,
h4,
.section-text,
.program-text,
.offer-cta {
    overflow-wrap: break-word;
}

.oranienbaum-regular {
  font-family: "Oranienbaum", serif;
  font-weight: 400;
  font-style: normal;
}

.eb-garamond {
  font-family: "EB Garamond", serif;
  font-optical-sizing: auto;
  font-weight: 400;
  font-style: normal;
}

.pinyon-script {
  font-family: "Pinyon Script", cursive;
  font-weight: 400;
  font-style: normal;
}

.nunito {
  font-family: "Nunito", sans-serif;
  font-optical-sizing: auto;
  font-weight: 100;
  font-style: normal;
}

@font-face {
    font-family: "WilliamNarasi";
    src: url("/fonts/WilliamNarasi.ttf");
}


@font-face {
    font-family: "Cherolina";
    src: url("/fonts/cherolina/Cherolina.otf");
}

a {
    color: black;
    text-decoration: none;
}

a:active:has(h1),
a:focus:has(h1),
a:hover:has(h1)
{
    text-decoration: none;
}

h1 {
    font-family: "WilliamNarasi", cursive;  
    font-size: 5rem;
}

h2 {
    font-family: "Pinyon Script", cursive;
    font-weight: 400;
    font-style: normal;
}

h2.single-word {
    
    font-size: calc(1.5rem + 4.5vw);
    /* 
    1920*1080 -> large desktop
    1728 * 1085 -> laptop
    1440px * 900px -> mac
    820 * 1180 -> ipad
    390 * 844 px -> iPhone 12 pro
    
    */
}

h2.double-word {
    font-size: calc(1.3rem + 4.5vw);

    @media (min-width:1200px) {
        font-size: calc(1rem + 4.5vw);
    }
}

h4 {
    font-family: "EB Garamond", serif;
}

.img-gift {
    border-radius: 25px;
}

.bg-img {
    background-size: cover;
    background-position: center;
    border-radius: 25px;
    min-height: 300px;
    @media (min-width:800px) {
        min-height: 400px;
        max-width: 280px;    
        min-width: 300px;
    }
}

.gift-text {
    position: absolute;
    top: 80%;
    left: 55%;
    transform: translate(-50%, -50%);
    z-index: 1;
    background-color: white;
    border-radius: 20px;
    filter: drop-shadow(3px 3px 4px #00000068);
}

.photo {
    background-image: url("/img/photographer.jpg");
}

.video {
    background-image: url('/img/videographe.jpg');
}

.piece-img {
    background-image: url('/img/piece.jpg');
}

.drink {
    background-image: url('/img/champagne.jpg');
}

.food {
    background-image: url('/img/buffet.jpg');
}

.planner {
    background-image: url('/img/planner.jpg');
}

.anchor {
    display: block;
    position: relative;
    top: -30vh;
    visibility: hidden;
}

.gift-text-v2 {
    background-color: white;
    border-radius: 20px;
    filter: drop-shadow(3px 3px 4px #00000068);
    @media (min-width:800px) {
        margin-inline: 2rem;
    }
}

.border-v {

    position: relative;

}

.hide {
    display: none;
}

.border-f {
    @media (min-width:1000px) {
        position: relative;
    }
}

/* This strip used to be a `.border-f::after` pseudo-element. A pseudo-element
   cannot be hovered, measured or given a data attribute, so it could not be
   made editable — it is now a real `.border-strip` div, the last child of
   `.border-f`, carrying the same declarations in the same place so it renders
   identically. It is hidden below 1000px exactly as the old `content: ""`
   inside the media query used to hide it. */
.border-strip {
    display: none;

    @media (min-width:1000px) {
        background-image: var(--ls-strip-image, url('/img/main-img.jpg'));
        width: 100%;
        height: 100px;
        display: block;
        background-position:right;
        background-size: cover;

        padding: 1rem;
        background-color: white;

        border: 1px solid #dee2e6;

        margin-top: 2rem;
        margin-bottom: 3rem;
    }
}

.border-f.right .border-strip {
    background-image: var(--ls-strip-image, url("/img/couple-1.JPG"));
    background-position: 50% 40%;
}

p {
    font-size: calc(1rem + 0.35vw);
    @media (width > 1800px) {
        font-size: calc(1rem + 0.4vw);
    }
    font-family: "EB Garamond", serif;
}

.border-v::before {

    @media (min-width: 100px) {
        transform: translate(14%, -5%);
        content: "";
        position: absolute;
        width: 80%;
        height: 80%;
        z-index: -1;
        max-width: 400px;
        border: solid 2px #7B1B38;
    }

    @media (min-width: 500px) {
        transform: translate(8%, -5%);
        content: "";
        position: absolute;
        width: 80%;
        height: 80%;
        z-index: -1;
        max-width: 400px;
        border: solid 2px #7B1B38;
    }
    
    @media (width > 799px) {
        content: "";
        position: absolute;
        width: 50%;
        height: 80%;
        z-index: -1;
        transform: translate(15%, -5%);
        border: solid 2px #7B1B38;
    }

    @media (width > 1000px) and (width < 1198px) {
        transform: translate(55%, -7%);
    }

    @media (width > 1199px) {
        content: "";
        position: absolute;
        width: 50%;
        height: 80%;
        z-index: -1;
        transform: translate(28%, -8%);
        border: solid 2px #7B1B38;
    }
    
}
    

.img-wrap {
  position: relative;
  display: inline-block;
}

.img-notice {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  color: #fff;
  font-size: 1.5rem;
  font-weight: bold;
  white-space: nowrap;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
  pointer-events: none;
}

.border-v.left::before {
    
    @media (min-width: 100px) {
        transform: translate(-6%, -5%);
        content: "";
        position: absolute;
        width: 80%;
        height: 80%;
        z-index: -1;
        max-width: 400px;
        border: solid 2px #7B1B38;
    }

    @media (min-width: 500px) {
        transform: translate(-3%, -5%);
        content: "";
        position: absolute;
        width: 80%;
        height: 80%;
        z-index: -1;
        max-width: 400px;
        border: solid 2px #7B1B38;
    }

    @media (min-width:577px) {
        transform: translate(-20%, -5%);
    }

    @media (width > 799px) {
        content: "";
        position: absolute;
        width: 50%;
        height: 80%;
        z-index: -1;
        transform: translate(-32%, -5%);
        border: solid 2px #7B1B38;
    }
    @media (width > 1000px) and (width < 1198px) {
        transform: translate(-15%, -7%);
    }

    @media (width > 1199px) {
        transform:translate(-15%, -8%);
    }
}

.couple-img {
    max-width: 100%;
    max-height: 500px;
}

.plus-btn {
    border: 0;
}

.offer-cta {
    font-family: "EB Garamond", serif;
    font-style: italic;
    color: #591427;
    margin-inline: auto;
    max-width: 40rem;
}


/* --ls-btn-bg and --ls-btn-text are published from the database in header.ejs
   and are editable from the page editor. The literals here are the fallback,
   and they must stay equal to the defaults in constants/content.slots.js. */
.give-btn {
    font-size: calc(1rem + 0.5vw);
    border-radius: 0.5rem;
    padding-inline: 4rem;
    background-color: var(--ls-btn-bg, #7B1B38);
    border-color: var(--ls-btn-bg, #7B1B38);
    color: var(--ls-btn-text, #ffffff);
    filter: drop-shadow(2px 2px 3px #00000068);
}

/* Darkened from whatever the current colour is, rather than a second hardcoded
   value — otherwise the hover state would ignore the admin's choice. */
.give-btn:hover,
.give-btn:focus,
.give-btn:active {
    background-color: var(--ls-btn-bg, #7B1B38);
    border-color: var(--ls-btn-bg, #7B1B38);
    color: var(--ls-btn-text, #ffffff);
    filter: drop-shadow(2px 2px 3px #00000068) brightness(0.85);
}

.vertical-line {
  --line-color: #591427;
  --dash-length: 10px;
  --dash-gap: 4px;

  display: block;
  height: 5vh;
  
  z-index: -1;
  pointer-events: none;
  mix-blend-mode: darken;

  
  background: linear-gradient(
    to right,
    transparent calc(50% - 0.5px),
    var(--line-color) calc(50% - 0.5px),
    var(--line-color) calc(50% + 0.5px),
    transparent calc(50% + 0.5px)
  );
  
  /* The mask makes the line appear to have gaps (AKA dashed) */
  mask-image: repeating-linear-gradient(
    to bottom,
    black 0,
    black var(--dash-length),
    transparent var(--dash-length),
    transparent calc(var(--dash-length) + var(--dash-gap))
  );
}

.program-text {
    margin-top: 5vh;

    /* A timeline entry used to be sized entirely by how tall its own text
       happened to be — 5vh above it and nothing at all below — so entries only
       looked evenly spaced because their descriptions wrapped to two or three
       lines in the narrow col-5. A short entry collapsed and sat almost on top
       of the next one, which is what a freshly added entry always is.
       The padding gives every entry the same breathing room below it whatever
       its length, and `min-height` stops a one-line entry from collapsing.
       Both lengthen the row, so `.vertical-line-v2` (top: 0 / bottom: 0 of the
       row) grows with it and the dashed line stays continuous. */
    padding-bottom: 4vh;
    min-height: 9rem;
}

.circle-line {
    width: 20px;
    height: 20px;
    padding: 0;
    background-color: #591427;
    border-radius: 50%;
    text-align: center;

    position: absolute;
    top: 5vh;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    justify-content: center;
    margin-left: auto;
    margin-right: auto;
}

.vertical-line-v2 {
    --line-color: #591427;
  --dash-length: 10px;
  --dash-gap: 4px;
  --dash-thickness: 0.5px;
    
    display: block;
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 1px;

    background: linear-gradient(
    to right,
    transparent calc(50% - var(--dash-thickness)),
    var(--line-color) calc(50% - var(--dash-thickness)),
    var(--line-color) calc(50% + var(--dash-thickness)),
    transparent calc(50% + var(--dash-thickness))
  );
  
  /* The mask makes the line appear to have gaps (AKA dashed) */
  mask-image: repeating-linear-gradient(
    to bottom,
    black 0,
    black var(--dash-length),
    transparent var(--dash-length),
    transparent calc(var(--dash-length) + var(--dash-gap))
  );
}

.circle-dash {
    --line-color: #591427;
    --dash-length: 5px;
    --dash-gap: 4px;
    /* Dash thickness desired value must be divided by 2 */
    --dash-thickness: 1px;
    width: 5vw;
    height: 10px;

    position: absolute;

    top: calc(5vh + 5px);
    left: 45%;
    @media (max-width: 800px) {
        left: 40%;
    }
    transform: translateX(-50%);


    pointer-events: none;
    mix-blend-mode: darken;
    

    background: linear-gradient(
    to bottom,
    transparent calc(50% - var(--dash-thickness)),
    var(--line-color) calc(50% - var(--dash-thickness)),
    var(--line-color) calc(50% + var(--dash-thickness)),
    transparent calc(50% + var(--dash-thickness))
  );
}



.circle-dash.right {
    
    left: 55%;
    @media (max-width: 800px) {
        left: 58%;
    }
    transform: translateX(-55%);
}

.section {
    margin-bottom: calc(2rem + 3vw);
}

.main-img {
    filter: blur(1.5px);
    clip-path: 20px;
}

.section-text {
    @media (min-width:1200px) {
        margin-bottom: 4rem;    
    }
    
}

.price {
    font-family: "JetBrains Mono", monospace;
    font-optical-sizing: auto;
    font-weight: 400;
    font-style: normal;
}

.circle-shape {
    max-width: 32px;
    color: white;
    height: 32px;
    padding: 0;
    border-radius: 100%;
    background-color: black;
}

.img-container {
    /* TODO */
    max-height: 90vh;
    height: 80vh;
    margin: auto 3em;
    /* Editable from the page editor; see the note on .give-btn. */
    background-image: var(--ls-hero-image, url("/img/main-img.jpg"));
    background-size: cover;
    background-position: center;
    
    @media (width < 1025px) {
        max-height: 60vh;
        height: 40vh;
    }
    @media (width < 821px) {
        margin: auto 2em;
    }
    @media (width < 400px) {
        max-height: 80vh;
        height: 40vh;
        margin: 0;
    }
    
}

.img-text {
    position: absolute;
    font-family: "EB Garamond", serif;
    z-index: 1;
    color: white;
    font-size: 10vw;
    filter: drop-shadow(2px 2px 1px #ffffff);
    @media (min-width: 800px) {
        filter: drop-shadow(5px 5px 2px #ffffff);
    }
    top: 50%;
    left: 50%;
    width: 100vw;
    text-align: center;
    transform: translate(-50%, -50%);
}

/* The two dates sit in the bottom-right of the hero photo, stacked and
   right-aligned. The panel itself reaches the corner; the *text* is held off
   the edge by the panel's own padding, which is also what gives the blur room
   to fade out.

   Separation from the photograph is done with a blurred backdrop rather than a
   hard shadow on the letters — see .dates-row::before. */
.dates-row {
    position: relative;

    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: clamp(0.6rem, 1.6vh, 1.4rem);

    /* Roomy on the left and top, where the blur has to fade into the photo. */
    padding:
        clamp(2rem, 6vh, 4rem)
        clamp(1.5rem, 4vw, 3.5rem)
        clamp(1.5rem, 4vh, 3rem)
        clamp(3rem, 9vw, 8rem);

    color: white;
    text-align: right;
}

/* The frosted panel.
 *
 * It lives on a pseudo-element, not on .dates-row itself, for one specific
 * reason: `mask-image` clips everything the element paints, so masking
 * .dates-row would fade out the dates along with the blur. Putting the blur and
 * the mask on a layer of their own leaves the text untouched.
 *
 * The mask is a single radial gradient anchored to the bottom-right corner, so
 * the blur is solid where the text sits and dissolves into the photograph in
 * both directions at once — no hard edge to notice.
 *
 * The gradient background is not decoration: it is the fallback. Where
 * backdrop-filter is unsupported it still darkens the corner enough to keep the
 * text readable, so nothing depends on the blur landing. */
.dates-row::before {
    content: "";
    position: absolute;
    inset: 0;

    background: linear-gradient(
        to top left,
        rgba(0, 0, 0, 0.45),
        rgba(0, 0, 0, 0.14) 58%,
        rgba(0, 0, 0, 0) 85%
    );

    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);

    -webkit-mask-image: radial-gradient(130% 140% at 100% 100%, #000 42%, transparent 80%);
    mask-image: radial-gradient(130% 140% at 100% 100%, #000 42%, transparent 80%);

    /* The photo underneath is an editable image slot; this layer must not
       swallow the hover that reveals its "Changer la photo" control. */
    pointer-events: none;
}

/* Positioned, so the dates paint above the panel. Without this they sit in the
   in-flow layer, which is *below* a positioned pseudo-element, and the blur
   would cover them. */
.dates-row-item {
    position: relative;
    min-width: 0;
}

/* On a phone the vertical padding above is a problem of units, not of values.
   It is measured in vh — against the viewport — but .img-container is only 40vh
   tall here against 80vh on a desktop, so the same declaration takes roughly
   double the share of the photo: the block came to about 62% of the image on a
   390x844 screen versus 38% on a laptop.
   Switching the vertical padding to rem ties it to the text instead of to the
   screen, which brings it back to about 45% and lets the dates sit near the
   bottom edge, as intended.
   The left padding stays generous on purpose: it is the room the blur needs to
   fade out horizontally, and tightening it makes the panel's left edge read as
   a hard line. */
@media (max-width: 576px) {
    .dates-row {
        padding: 1.25rem 1.1rem 0.9rem 2.75rem;
        gap: 0.45rem;
    }
}

.dates-border.right {
    height: 100%;
    width: 100%;
    position:absolute; 
    z-index:2;
    top: 0;
    right: 0;
    transform: translate(40%, -20%);
}
.dates-border.left {
    height: 100%;
    width: 100%;
    position:absolute; 
    z-index:3;
    top: 0;
    right: 0;
    
    transform: translate(-40%, 10%);
    @media (width < 500px) {
        transform: translate(-40%, 10%);;
    }
}

.dates-border {
    stroke:#ff1100;
    stroke-width:0.5px;
    fill:none;
    stroke-linejoin:miter;
}


/* A soft shadow, not the hard offset one this used to carry: the frosted panel
   behind the text is what separates it from the photograph now, and a blocky
   drop-shadow on top of that reads as two competing effects. This is only
   insurance for a bright patch of photo. */
.dates-row h2,
.dates-row h4 {
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.5);
}



.border-l::before {
    @media (min-width:1000px) {
        content: "";

        padding: 1rem;
        
        border: 1px solid #dee2e6;
    }
}

.date-title {
    /* font-family: "EB Garamond", serif; */
    font-family: "Bodoni Moda", serif;
    font-optical-sizing: auto;
    font-weight: 300;

    /* Sized explicitly rather than left to Bootstrap's h2, so the pair keeps a
       deliberate relationship to each other at every width. */
    margin-bottom: 0.1rem;
    font-size: clamp(1.5rem, 2.6vw, 2.6rem);
    line-height: 1.15;
}

/* Pinyon Script is a script face: it reads much smaller than its point size, so
   it needs to be set larger than the date to carry equal weight on the photo.
   Large enough to be legible over the image, short of competing with the
   couple's names above it. */
.location-title {
    font-family: "Pinyon Script", cursive;
    white-space: nowrap;

    margin-bottom: 0;
    font-size: clamp(1.35rem, 2.3vw, 2.3rem);
    line-height: 1.2;
}

/* Programme — ceremony tabs and per-entry time */

/* The two ceremonies sit centred under the "Programme" heading, on the same
   vertical axis as it. A flex row that is centred as a group does that on its
   own, and keeps the pair centred however long the two names are. */
.program-tabs-row {
    margin-bottom: 1.5rem;
}

.program-tabs {
    display: inline-flex;
    align-items: stretch;
    gap: 0;

    /* The space between the two names is the tabs' own horizontal padding, so
       the underline can be inset from it and stay tied to the label's width. */
    --tab-pad: 2.3rem;
}

/* Made to read as a control without shouting: the site's body serif, a resting
   state that is clearly muted against the active one, and an underline that
   grows out from the centre on selection. The underline is a pseudo-element
   scaled on the X axis, so nothing reflows as it animates. */
.program-tab {
    position: relative;

    padding: 0.35rem var(--tab-pad) 0.6rem;

    font-family: "EB Garamond", serif;
    font-size: calc(1rem + 0.55vw);
    line-height: 1.2;
    color: rgba(0, 0, 0, 0.42);

    background: none;
    border: 0;
    cursor: pointer;
    transition: color 0.22s ease, transform 0.22s ease;
}

.program-tab::after {
    content: "";
    position: absolute;
    left: calc(var(--tab-pad) - 0.55rem);
    right: calc(var(--tab-pad) - 0.55rem);
    bottom: 0.15rem;
    height: 2px;

    background: #7B1B38;
    transform: scaleX(0);
    transition: transform 0.26s cubic-bezier(0.2, 0.8, 0.3, 1);
}

.program-tab:hover,
.program-tab:focus-visible {
    color: rgba(0, 0, 0, 0.75);
    transform: translateY(-1px);
    outline: none;
}

.program-tab:hover::after,
.program-tab:focus-visible::after {
    transform: scaleX(0.45);
}

.program-tab.is-active {
    color: #591427;
}

.program-tab.is-active::after {
    transform: scaleX(1);
}

.program-tab:focus-visible {
    text-decoration: underline dotted rgba(0, 0, 0, 0.35);
    text-underline-offset: 0.6rem;
}

/* Only the selected ceremony's timeline is shown. */
.program-panel {
    display: none;
}

.program-panel.is-active {
    display: block;
}

/* The time under an entry's heading. Deliberately quiet — it is a detail, not
   a second title — and it inherits the row's alignment, so it needs no
   left/right variants of its own. It is only rendered when it has a value, so
   entries without a time look exactly as they did before it existed. */
.program-time {
    margin-top: -0.15rem;
    margin-bottom: 0.35rem;

    font-family: "EB Garamond", serif;
    font-size: 0.82rem !important;
    font-style: italic;
    letter-spacing: 0.06em;
    color: #7B1B38;
    opacity: 0.75;
}

@media (max-width: 576px) {
    .program-tabs {
        --tab-pad: 1.3rem;
    }

    .program-tab {
        font-size: 1.05rem;
    }
}

/* ------------------------------------------------- programme: place + map

   The small line under a timeline entry saying where that step happens. It is
   deliberately quieter than the title and the time: it is reference
   information a guest looks for once, not something to compete with the
   entry's name.

   Three renderings share .program-place — an <a> when the couple added a map
   link, a <span> when they did not, and a <span> plus the editor's link button
   in edit mode. Keeping the typography on the shared class is what stops the
   line moving when a link is added. */

.program-place-line {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;

    margin-top: 0.1rem;
    margin-bottom: 0;
}

/* .text-end sets text-align, which does nothing to a flex container — the
   right-hand entries need their items moved instead. */
.program-place-line.text-end {
    justify-content: flex-end;
}

.program-place {
    display: inline-flex;
    align-items: baseline;
    gap: 0.33rem;

    font-family: "EB Garamond", serif;
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    color: #6f6a68;
}

.program-pin {
    flex: 0 0 auto;
    /* Nudged down to sit on the text's baseline rather than its cap height. */
    transform: translateY(1px);
    color: #7B1B38;
    opacity: 0.8;
}

/* Only the linked variant is coloured and underlined, so a place with no map
   link does not look like a dead link. */
a.program-place-link {
    color: #7B1B38;
    text-decoration: none;
    border-bottom: 1px solid rgba(123, 27, 56, 0.35);
    transition: border-color 0.15s ease, color 0.15s ease;
}

a.program-place-link:hover,
a.program-place-link:focus-visible {
    color: #5c1429;
    border-bottom-color: currentColor;
}

a.program-place-link:focus-visible {
    outline: 2px solid rgba(123, 27, 56, 0.45);
    outline-offset: 3px;
    border-radius: 2px;
}

@media (max-width: 576px) {
    .program-place {
        font-size: 0.72rem;
    }
}
