/* ==========================================================================
   Event details page (Figma: QF - BilAraby - WebsiteDesign-Concept-2,
   node 40001286:71210 "Event Details"). Reuses the --hr-* tokens declared
   globally in layout-revamp.css, and the .evt-grid / .evt-card / .evt-chip /
   .evt-btn-primary / .evt-btn-ghost / .evt-modal styles from
   events-revamp.css for the "You may also Like" grid and the shared Register
   modal — same technique podcasts-detail-revamp.css uses with
   podcasts-revamp.css's .pod-grid/.pod-card.

   No photo banner — the same flat blue "liquid" gradient wash the Events
   listing page's hero uses, bled tall enough to wash over the header card
   below (as podcasts-detail-revamp.css's wash does over .podd-episode). */
.event-detail-revamp .hr-accent { color: var(--hr-yellow-500); }
/* Stops are fixed px (sampled from Figma's actual hero asset, node
   40001286:71212), not %, so the wash reads the same colour at the same
   height as events-revamp.css's identical hero wash — a %-based curve looks
   different depending on the element's total height, which is why this and
   events-revamp's wash used to drift apart even with the same stop list. */
.event-detail-revamp {
    position: relative;
    overflow-x: hidden;
    /* cream-500, not cream-400. The artboard paints ONE cream down the whole
       page: sampling the gutter of the exported design (node 40001286:71210)
       at 10px intervals returns rgb(249,247,233) - #f9f7e9 - 61 times over,
       with no second shade anywhere. .evtd-agenda was already on it, so the
       page underneath it sat one step lighter and every seam between the two
       showed as a faint band - most visibly around the gold rule, whose own
       strip is page background. */
    background: var(--hr-cream-500) linear-gradient(to bottom,
        rgba(0, 80, 135, .98) 0,
        rgba(0, 80, 135, .82) 145px,
        rgba(0, 80, 135, .57) 210px,
        rgba(0, 80, 135, .30) 270px,
        rgba(0, 80, 135, 0) 340px) no-repeat top center;
    background-size: 100% 700px;
}
/* Figma's hero asset carries a fine grain/noise texture baked into the PNG
   (same reason bilaraby-talks-revamp.css/press-releases-revamp.css keep a
   checked-in banner instead of a flat gradient) — a plain linear-gradient()
   can't reproduce that, it renders perfectly flat/plastic instead of the
   "brushed" look. Re-add it as a tiny tiled feTurbulence SVG blended over
   the gradient rather than switching back to a raster banner. The
   feComponentTransfer re-centers the turbulence output to ~mid-gray before
   the overlay blend — without it the raw noise is skewed bright, so overlay
   tints the whole wash lighter instead of just adding grain. opacity:.5 was
   picked by measuring Figma's real hero asset (~7-8 stdev of per-pixel
   variation) and matching that same variance here. */
.event-detail-revamp::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 700px;
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxODAnIGhlaWdodD0nMTgwJz48ZmlsdGVyIGlkPSduJz48ZmVUdXJidWxlbmNlIHR5cGU9J2ZyYWN0YWxOb2lzZScgYmFzZUZyZXF1ZW5jeT0nMC44NScgbnVtT2N0YXZlcz0nMicgc3RpdGNoVGlsZXM9J3N0aXRjaCcvPjxmZUNvbG9yTWF0cml4IHR5cGU9J3NhdHVyYXRlJyB2YWx1ZXM9JzAnLz48ZmVDb21wb25lbnRUcmFuc2Zlcj48ZmVGdW5jUiB0eXBlPSdsaW5lYXInIHNsb3BlPScxJyBpbnRlcmNlcHQ9Jy0wLjIzMDInLz48ZmVGdW5jRyB0eXBlPSdsaW5lYXInIHNsb3BlPScxJyBpbnRlcmNlcHQ9Jy0wLjIzMDInLz48ZmVGdW5jQiB0eXBlPSdsaW5lYXInIHNsb3BlPScxJyBpbnRlcmNlcHQ9Jy0wLjIzMDInLz48L2ZlQ29tcG9uZW50VHJhbnNmZXI+PC9maWx0ZXI+PHJlY3Qgd2lkdGg9JzEwMCUnIGhlaWdodD0nMTAwJScgZmlsdGVyPSd1cmwoI24pJy8+PC9zdmc+");
    background-repeat: repeat;
    opacity: .5;
    mix-blend-mode: overlay;
    pointer-events: none;
    z-index: 0;
}
.evtd-hero-decor {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 256px;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}
.evtd-hero-decor img {
    position: absolute;
    bottom: 0;
    width: 37%;
    height: 100%;
    object-fit: cover;
    object-position: top;
    mix-blend-mode: overlay;
}
.evtd-hero-decor-right { left: 63%; }
.evtd-hero-decor-left { left: -3%; transform: scaleX(-1); }
[dir="rtl"] .evtd-hero-decor-right { left: auto; right: 63%; transform: scaleX(-1); }
[dir="rtl"] .evtd-hero-decor-left { left: auto; right: -3%; transform: scaleX(1); }

/* ---------- Hero / breadcrumb ---------- */
.evtd-hero {
    position: relative;
    z-index: 1;
    height: 256px;
    display: flex;
    align-items: flex-end;
    padding: 0 160px 24px;
}
.evtd-hero-inner { position: relative; z-index: 1; max-width: 1600px; width: 100%; margin-inline: auto; }
.evtd-breadcrumb-row { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.evtd-breadcrumb { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; font-size: 20px; color: var(--hr-cream-500); text-transform: uppercase; }
/* Full strength per Figma's Breadcrumb component - only font weight marks the
   current crumb, there is no resting opacity on the others. Full note in
   press-releases-revamp.css. */
.evtd-breadcrumb a,
.evtd-breadcrumb span:not(.evtd-breadcrumb-sep) { opacity: 1; }
.evtd-breadcrumb a { color: inherit; text-decoration: none; transition: opacity .2s ease; }
.evtd-breadcrumb a:hover { opacity: 1; color: inherit; text-decoration: underline; }
.evtd-breadcrumb-current { font-weight: 700; opacity: 1 !important; }
.evtd-breadcrumb-sep { width: 1px; height: 16px; background: rgba(249, 247, 234, .5); flex-shrink: 0; }
.evtd-hero-divider { display: none; }
@media (min-width: 1200px) {
    .evtd-hero-divider {
        display: flex;
        align-items: center;
        flex-shrink: 0;
        width: 280px;
        margin-inline-end: calc(-160px - max(0px, (100vw - 1920px) / 2));
    }
    /* Figma (node 40001286:71369): 20px squares stepped exactly 20*sqrt(2) =
       28.284px apart, so their rotated bounding boxes are edge-to-edge - tips
       touching, 0px visible gap, no merge.

       The spacing is 20*(sqrt(2)-1)/2 = 4.142px of margin on EACH SIDE of every
       diamond, not a `gap` on the row. Same recipe as .pr-hero-divider /
       .abt-diamond / .pp-diamond / .tnc-diamond - and the reason those carry it
       on the diamond is the bug this had: a row `gap` spaces the diamonds from
       each other but gives the LAST one nothing between it and the rule, so with
       gap:8.3px plus the line's own 4px start margin the rule began 8.15px clear
       of the final tip (measured) instead of meeting it. Every other page reads
       0. A diamond's own side margin spaces it off the line as well. */
    .evtd-hero-divider .evtd-diamond {
        width: 20px;
        height: 20px;
        margin-inline: 4.142px;
        transform: rotate(45deg);
        background: var(--hr-cream-500);
        flex-shrink: 0;
    }
    /* margin-inline-start: 0 - the last diamond's own margin supplies the
       spacing now, so anything here would add back a visible gap. */
    .evtd-hero-divider-line { flex: 1 1 auto; height: 1px; background: rgba(249, 247, 234, .5); margin-inline-start: 0; }
}
.evtd-hero::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 1px;
    background: rgba(249, 247, 234, .35);
}

/* ---------- Header (title / meta / description / author / actions + media / stats) ---------- */
/* padding-bottom is real (not 0): .evtd-header's two columns don't stretch to
   match height (align-items:flex-start), so whichever column is shorter for
   a given event (e.g. no seats pill/author block, or a short stats row)
   would otherwise butt straight up against the divider below with no
   guaranteed clearance — this bottom padding is that guarantee regardless
   of which column ends up tallest. */
.evtd-header-wrap { position: relative; z-index: 1; padding: 120px 160px 48px; }
.evtd-header-inner { max-width: 1600px; margin-inline: auto; }
.evtd-header { display: flex; align-items: flex-start; gap: 60px; }
.evtd-header-main { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 40px; }
.evtd-title-block { display: flex; flex-direction: column; gap: 24px; }
.evtd-title { margin: 0; font-size: 64px; line-height: 72px; font-weight: 700; color: var(--hr-brown-900); }
.evtd-meta-row { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.evtd-seats { display: inline-flex; align-items: center; gap: 8px; font-size: 18px; color: var(--hr-brown-400, #49473d); }
.evtd-seats-dot { flex-shrink: 0; width: 5px; height: 5px; border-radius: 50%; background: var(--hr-brown-400, #49473d); }
.evtd-desc { margin: 0; font-size: 24px; line-height: 32px; color: var(--hr-brown-300); }

.evtd-author { display: flex; align-items: center; gap: 16px; }
.evtd-author-avatar {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-size: cover;
    background-position: center;
    background-color: var(--hr-brown-300);
}
.evtd-author-text { display: flex; flex-direction: column; }
.evtd-author-name { font-size: 18px; font-weight: 700; color: var(--hr-brown-900); }
.evtd-author-role { font-size: 14px; color: var(--hr-brown-300); }

.evtd-actions { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; position: relative; }
.evtd-btn-primary,
.evtd-btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 16px 24px;
    border-radius: 61px;
    font-size: 16px;
    font-weight: 700;
    border: 1.5px solid transparent;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    box-shadow: inset 0 4px 6.1px rgba(255, 255, 255, .23), 0 3px 6px rgba(0, 0, 0, .03);
    transition: transform .2s ease, background-color .2s ease;
}
.evtd-btn-primary:hover { transform: translateY(-2px); }
.evtd-btn-ghost:hover { transform: translateY(-2px); }
.evtd-btn-primary { background: var(--hr-yellow-500); color: #fff; }
.evtd-btn-primary:hover { color: #fff; }
/* Register Now, matched to the Annual Gathering hero's button exactly - same
   figures as .summit-revamp .smt-hero-copy .hr-btn-primary in summit-revamp.css.
   The glass rim and hover glow live in layout-revamp.css; this selector is
   added to those lists there, which that rule's comment asks to be kept
   explicit rather than widened to a shared ancestor.

   .hr-btn carries no cross-page base block - each page wrapper declares its own
   (.header-revamp/.footer-revamp in layout-revamp.css, .summit-revamp in
   summit-revamp.css), so without these two the button rendered square and at
   normal weight. Copied from .summit-revamp .hr-btn / .hr-btn-primary verbatim,
   scoped to .evtd-actions since that is the only .hr-btn on this page. */
.event-detail-revamp .evtd-actions .hr-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: flex-start;
    gap: 8px;
    padding: 16px 24px;
    border-radius: 61px;
    font-weight: 700;
    font-size: 16px;
    border: 1.5px solid transparent;
    text-decoration: none;
    white-space: nowrap;
    transition: transform .2s ease, box-shadow .2s ease;
}
.event-detail-revamp .evtd-actions .hr-btn:hover { transform: translateY(-2px); text-decoration: none; }
.event-detail-revamp .evtd-actions .hr-btn-primary {
    background: var(--hr-yellow-500);
    color: var(--hr-cream-50);
    border-color: #fff;
    box-shadow:
        inset 0 4px 6.1px rgba(255,255,255,.23),
        7px 63px 18px rgba(0,0,0,.02),
        2px 23px 14px rgba(0,0,0,.02),
        1px 10px 10px rgba(0,0,0,.03),
        0 3px 6px rgba(0,0,0,.03);
}
.event-detail-revamp .evtd-actions .hr-btn-primary:hover { color: var(--hr-cream-50); box-shadow: 0 8px 20px rgba(217,133,0,.35); }
.event-detail-revamp .evtd-actions .hr-btn-primary {
    padding: 14.5px 22.5px;
    border: 2px outset #ffffff9c;
    border-bottom-width: 0;
    font-size: 16px;
    line-height: 24px;
}
.event-detail-revamp .evtd-actions .hr-btn-primary:hover {
    box-shadow:
        inset 0 4px 6.1px rgba(255,255,255,.23),
        7px 63px 18px rgba(0,0,0,.02),
        2px 23px 14px rgba(0,0,0,.02),
        1px 10px 10px rgba(0,0,0,.03),
        0 3px 6px rgba(0,0,0,.03);
}
/* Figma (node 40001286:71393 "View All Events", same Button component as
   the home page's .hr-btn-ghost-dark): fill rgba(255,255,255,.2), text
   brown-500 (#1b190c, not brown-900), and a 3-stop gradient stroke.

   BIL-710: the stroke used to be a second background layer clipped to
   border-box, under a padding-box fill layer. A background layer paints
   everywhere its clip allows, so it also painted behind the translucent
   fill and its #65686f stop showed through as a grey band across the
   button's face. The stroke is the shared masked ring in layout-revamp.css
   now, so the fill is just a fill. */
.evtd-btn-ghost {
    /* White, not the component's rgba(255,255,255,.2). That token composites to
       rgb(251,250,241) over this page's cream — near enough the page colour that
       the button reads as a flat grey wash rather than a button, which is the
       reported problem.
       Worth recording: Figma's own render of THIS row (node 40001286:71232)
       comes out greyer still — rgb(234,233,224) against a rgb(249,247,233)
       page, i.e. DARKER than the background — so the design file and the
       approved reference disagree here. Built to the reference: a white face
       lifting to pure white along the bottom, which is also what the component's
       own bottom bloom (see ::before) is reaching for. Bottom-up so the gradient
       runs the same direction as that bloom instead of fighting it. */
    background: linear-gradient(to top, #ffffff 0%, #fcfbf8 55%, #f7f6f1 100%);
    border-color: transparent;
    color: var(--hr-brown-500);
    /* Same 0-alpha shadow layers Figma lists (7px/63px, 4px/40px) are dead
       weight - only these four actually paint anything. */
    box-shadow:
        inset 0 4px 6.1px rgba(255,255,255,.23),
        2px 23px 14px rgba(0,0,0,.02),
        1px 10px 10px rgba(0,0,0,.03),
        0 3px 6px rgba(0,0,0,.03);
    /* Border folded into the padding so the button keeps its height while
       clipping its own overflow, which is what lets the bloom below be trimmed
       to the pill. --hr-ring-inset:0 then puts the shared masked rim back on
       the outer edge (same override .smt-attend-btn uses for the same reason);
       left at -1.5px it would sit outside the padding box and be clipped away.

       15.5px block, not 17.5: this button sits in .evtd-actions next to Register
       Now, and at 17.5 it stood 59px against that button's 55px - visible on the
       "Share" pill especially, which wraps onto its own row where nothing else
       sets the eye level. 55px is not arbitrary either: `padding: 14.5px 22.5px`
       on .hr-btn is a sitewide figure (17 stylesheets carry it), so the row now
       matches the site's button height rather than this page inventing a third
       one. 15.5 * 2 + 24px of line box = 55. Inline padding keeps its own +1.5
       border compensation. */
    border-width: 0;
    padding: 15.5px 25.5px;
    overflow: hidden;
    --hr-ring-inset: 0px;
    /* Own stacking context, so the bloom's plus-lighter blends against this
       button's fill and not the page behind it. */
    isolation: isolate;
}
/* Figma's "Ellipse 262": a 100px white circle at 40% opacity, Gaussian-blurred
   (stdDeviation 18.55) and composited plus-lighter. Every other button in the
   revamp drops it on purpose - there it sits at top:59.55px inside a clipped
   56px box and never renders. THIS instance (node 40001286:71393) hangs it off
   the BOTTOM instead, at bottom:-102.55px, so the blur tail reaches 34.55px up
   into the pill. That bloom is the whole difference between the design's bright
   white button and the flat grey wash a bare rgba(255,255,255,.2) fill gives
   over this page's cream: 20% white over #f9f7e9 composites to rgb(250,249,237),
   i.e. near enough the page colour, which is why these read as dull grey.
   Additive white saturates that to a true white across the bottom third.
   ::before, because ::after is already the shared rim in layout-revamp.css. */
.evtd-btn-ghost::before {
    content: "";
    position: absolute;
    z-index: -1;
    left: calc(50% + .5px);
    bottom: -102.55px;
    width: 100px;
    height: 100px;
    transform: translateX(-50%);
    border-radius: 50%;
    background: rgba(255,255,255,.4);
    filter: blur(18.55px);
    mix-blend-mode: plus-lighter;
    pointer-events: none;
}
.evtd-btn-ghost:hover {
    color: var(--hr-brown-500);
    background: rgba(255,255,255,.3);
}
[dir="rtl"] .evtd-btn-primary img,
[dir="rtl"] .evtd-btn-ghost img { transform: scaleX(-1); }
.evtd-share { position: relative; }
.evtd-share-menu {
    position: absolute;
    top: calc(100% + 12px);
    inset-inline-start: 0;
    display: flex;
    gap: 8px;
    padding: 12px;
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 12px 32px rgba(11, 11, 5, .16);
    z-index: 2;
}
.evtd-share-menu a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 30px;
    background: rgba(0, 0, 0, .05);
    color: var(--hr-brown-900);
    text-decoration: none;
}
.evtd-share-menu a:hover { background: var(--hr-green-500); color: var(--hr-cream-50); }

.evtd-header-media { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 60px; }
.evtd-media {
    position: relative;
    height: 507px;
    border-radius: 30px;
    overflow: hidden;
    background-color: var(--hr-brown-300);
}
.evtd-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* No usable image: the panel keeps its 507px and carries the title's first two
   letters. Cream on brown-500, the same pair .blgd-cover-empty uses, so an
   event without a picture looks the same as an article without one.
   The initials are in the DOM unconditionally and hidden here, because the
   img's onerror has to have something to reveal - see events/show. */
.evtd-media-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--hr-brown-500);
}
.evtd-media-initials {
    display: none;
    font-size: 200px;
    line-height: 1;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--hr-cream-500);
    /* Only latin has case to raise; an Arabic pair is left as it is. */
    text-transform: uppercase;
    /* Keeps the pair in the title's own direction inside this otherwise-LTR
       box rather than the page's. */
    unicode-bidi: isolate;
}
.evtd-media-empty .evtd-media-initials { display: block; }

/* Grid, not flex: with flex-wrap a long location/language string could push
   the row past the container width and wrap the whole 3rd stat onto its own
   line (reported as the date/location/language row collapsing to 2 rows on
   Doha Convention Center). Grid locks it to exactly 3 equal columns — a long
   word wraps inside its own column instead of reflowing the layout. */
.evtd-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: flex-start; gap: 16px; }
/* align-items: center (not flex-start) here would centre each icon against
   its OWN stat's text height - fine when every stat wraps the same way, but
   date/location/language don't: whichever one happens to wrap onto an extra
   line grows taller than its neighbours, and centering pulls just that one
   icon down relative to the other two. flex-start pins every icon to the
   top of its stat regardless of how many lines its own text wraps to,
   keeping all three level with each other. */
.evtd-stat { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.evtd-stat-icon {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: 11px;
    border: 1px solid #fff;
    /* Glass per Figma node 40002817:89638, which specifies all three parts:

       1. a translucent top-gradient fill (white .6 -> .45) - NOT an opaque
          white. An earlier pass here made it #fff on the reasoning that a
          translucent fill has nothing to refract on this cream section; the
          node says otherwise, so the gradient stands.
       2. backdrop-blur 61.2px, over that fill.
       3. an OUTER five-layer ambient drop shadow - this is what was actually
          missing, and what the tile needs to lift off the cream the way the
          home page's buttons do. Two of Figma's five layers are fully
          transparent (8/72 and 4.571/45.714 at alpha 0) and are dropped, the
          same convention .agd-pdf-btn documents. The remaining three, divided
          by the node's 1.143 scale (its border is 1.143px where ours is 1px),
          land exactly on the stack .evt-card and .pr-card already use.

       The inset white sheen is Figma's `inset 0 4.571px 6.971px` at the same
       scale, i.e. the 4/6.1 the rest of the site uses; kept at 4.5/7 as it
       was, which is within a rounding of both. */
    background: linear-gradient(to top, rgba(255, 255, 255, .45), rgba(255, 255, 255, .6) 76%, rgba(255, 255, 255, .6));
    -webkit-backdrop-filter: blur(61px);
    backdrop-filter: blur(61px);
    box-shadow:
        inset 0 4.5px 7px rgba(255, 255, 255, .23),
        2px 23px 7px rgba(0, 0, 0, .02),
        1px 10px 5px rgba(0, 0, 0, .03),
        0 3px 3px rgba(0, 0, 0, .03);
    /* The edge is the shared masked rim, wired the same way the Share button
       (.evtd-btn-ghost) on this page does it: the class is listed in
       layout-revamp.css's two rim lists, the border is folded away, and
       --hr-ring-inset:0 puts the rim on the outer edge instead of the -1.5px
       default (which assumes a 1.5px transparent border to sit in - this tile
       had a 1px one, so the rim would have overhung it by half a pixel).

       border-width:0 rather than a transparent border: with box-sizing
       border-box and a fixed 64px, dropping it keeps the tile exactly 64px and
       the flex-centred icon does not move - it just replaces Figma's flat white
       hairline with the three-stop gradient rim, which is what carries the glass
       on every other control here. */
    border-width: 0;
    --hr-ring-inset: 0px;
}
.evtd-stat-icon img { width: 32px; height: 32px; }
.evtd-stat-text { display: flex; flex-direction: column; min-width: 0; }
.evtd-stat-text strong { font-size: 24px; line-height: 32px; font-weight: 700; color: var(--hr-brown-700); overflow-wrap: break-word; }
.evtd-stat-text span { font-size: 20px; line-height: 28px; color: var(--hr-brown-100, #b8b8b4); overflow-wrap: break-word; }

/* ---------- Divider between sections ---------- */
.evtd-divider { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; padding-inline: 160px; height: 28px; }
.evtd-divider::before { content: ""; position: absolute; inset-inline: 0; top: 50%; height: 1px; background: var(--hr-yellow-400); opacity: .6; }
/* The chip masks the rule behind the diamonds, so it has to be the exact colour
   of the strip it sits on - now the page's cream-500. At cream-400 it read as a
   lighter patch behind each cluster. */
.evtd-divider-diamonds { position: relative; z-index: 1; display: flex; align-items: center; background: var(--hr-cream-500); }
/* Figma (node 40001286:71369): sharp-cornered 20px squares stepped exactly
   20*sqrt(2) = 28.284px apart, i.e. touching corner-to-corner with 0px
   gap. This wrapper's border-radius:4px was rounding away exactly the
   corner tip each diamond needs to touch its neighbor with, reading as a
   visible gap at every seam even though the boxes themselves were already
   the right size. */
.evtd-divider-diamond { width: 28.284px; height: 28.284px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.evtd-divider-diamond::before { content: ""; width: 20px; height: 20px; background: #f3d9b0; transform: rotate(45deg); }
/* .evtd-section's own 120px padding-top/bottom stacks on top of the divider
   itself, reading as a much bigger gap around the diamonds than Figma's
   tight spacing there — trim just the edge touching the divider. */
.evtd-divider + .evtd-section { padding-top: 60px; }
.evtd-section:has(+ .evtd-divider) { padding-bottom: 60px; }
/* About and Programme sit back-to-back with no divider between them (unlike
   every other section pair on this page) — their default 120px paddings
   were stacking into a 240px gap that read as a lot more empty space than
   any other seam on the page. */
.evtd-section:has(+ .evtd-section) { padding-bottom: 40px; }
.evtd-section + .evtd-section { padding-top: 40px; }
/* The video block is full-bleed - neither an .evtd-section nor a divider - so
   neither trim above caught the About section's bottom edge, and it kept the
   default 120px. That left it the only seam on the page touching a neighbour
   that was not 60 (divider) or 40 (section-to-section), and against a block
   whose own BOTTOM edge the following divider sits flush to, so the video read
   as pushed down the page. 60 is the divider figure, which also makes About
   symmetric with the 60 it already takes from the divider above it.

   Only for the video: with no video on the event, About's next sibling is that
   divider and the rule above it already gives the same 60. */
.evtd-section:has(+ .evtd-video-bleed) { padding-bottom: 60px; }

/* ---------- About + Map ---------- */
.evtd-section { position: relative; z-index: 1; padding: 120px 160px; }
.evtd-section-inner { max-width: 1600px; margin-inline: auto; }
.evtd-about-row { display: flex; gap: 60px; align-items: stretch; }
.evtd-about-copy { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 32px; }
.evtd-about-copy h2 { margin: 0; font-size: 40px; line-height: 48px; font-weight: 700; color: var(--hr-brown-500); }
.evtd-about-copy p { margin: 0; font-size: 20px; line-height: 28px; color: #3e3d30; }
.evtd-about-copy p + p { margin-top: -8px; }

/* Default/generic venue-map graphic (Figma "Map" component, node
   40001286:71289) — not tied to the event's real location since there's no
   lat/lng or map integration in the Event model, only its plain-text
   `location`. The whole card is a link to a Google Maps search for that
   text, so the "Get Direction" action is real even though the picture
   behind it is a shared default.

   This used to be ONE flattened raster (photo + signpost + "Get Direction"
   text + arrow baked together), which meant the arrow could never move for
   Arabic — flipping the whole raster for RTL would have mirrored the baked
   English text into unreadable backwards text. Rebuilt from Figma's actual
   layer split instead: a background photo, a text-free signpost graphic
   (map-signpost.svg), and a real text+button overlay on top. The overlay
   reorders itself for RTL for free via flexbox + the inherited `dir`; only
   the arrow glyph itself needs an explicit flip to point the right way. */
.evtd-map {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    display: block;
    /* align-self:start so this card's own aspect-ratio decides its height.
       .evtd-about-row is align-items:stretch, which otherwise forces the cross
       size to the row's height - and with flex-basis:0 this card contributes
       nothing to that height, so the row was sized by the copy column alone.
       That went unnoticed while the copy always carried an <h2>: the map's
       aspect height was the taller of the two, so stretch matched it anyway.
       Now that the section heading is optional, an event with one line of
       description and no heading left a 28px row - and the map stretched down
       to a 2px sliver. */
    align-self: start;
    aspect-ratio: 770 / 467;
    border-radius: 32px;
    overflow: hidden;
    border: 1px solid #fff;
}
.evtd-map-bg {
    position: absolute;
    inset: 0;
    background: url('../images/events-revamp/map-bg-photo.webp') center / cover no-repeat;
}
.evtd-map-bg::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(184deg, rgba(249, 247, 233, 0) 28%, rgba(249, 247, 233, .5) 86%);
}
/* The blur half of Figma's "Rectangle 25812" treatment. The cream wash above
   was carried over on its own, so this map softened by colour alone while the
   contact page's (.cta-map-blur in contact-revamp.css) also blurs what is
   behind it - the same rectangle, same 7.35px radius, so the two pages read
   as one component.

   Bottom-anchored and sized as a share of the card rather than in px, for the
   reason contact gives: the card is aspect-ratio'd, so a fixed band would be
   a different fraction of it at every width. 38.235% is contact's own
   260/680, which puts the blur under the wash's strongest stop (86%) and
   leaves the upper map crisp.

   Its own layer rather than a filter on ::after, which covers the whole card
   (inset: 0) and would have blurred the map top to bottom. ::before paints
   first, so the wash still sits over it, and the signpost and overlay are
   later siblings of .evtd-map-bg - they stay sharp, as in the design. */
.evtd-map-bg::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 38.235%;
    pointer-events: none;
    -webkit-backdrop-filter: blur(7.35px);
    backdrop-filter: blur(7.35px);
}
/* Percentages below are the signpost's/overlay's exact Figma frame, converted
   to a fraction of the outer 770x467 "Map" canvas — see node 40001286:71289
   for the source rects. The signpost's own height (79.44%) runs past the
   card's bottom edge on purpose (its pole legs are cropped there in Figma
   too); .evtd-map's overflow:hidden clips it the same way. */
.evtd-map-signpost { position: absolute; inset-inline-start: 23.23%; top: 39.83%; width: 53.54%; height: 79.44%; }
.evtd-map-overlay {
    position: absolute;
    inset-inline-start: 30.75%;
    top: 54.66%;
    width: 39.74%;
    height: 16.28%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.evtd-map-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; color: var(--hr-cream-500, #f9f7ea); white-space: nowrap; overflow: hidden; }
.evtd-map-label { font-size: 16px; line-height: 24px; overflow: hidden; text-overflow: ellipsis; }
.evtd-map-location { font-size: 24px; line-height: 32px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; }
.evtd-map-btn {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 61px;
    border: 1.5px solid transparent;
    background: rgba(255, 255, 255, .2);
    box-shadow: inset 0 4px 6.1px rgba(255, 255, 255, .23);
}
.evtd-map-btn img { width: 24px; height: 24px; filter: brightness(0) invert(1); }
[dir="rtl"] .evtd-map-btn img { transform: scaleX(-1); }
@media (max-width: 575.98px) {
    .evtd-map-label { display: none; }
    .evtd-map-location { font-size: 18px; line-height: 24px; }
    .evtd-map-btn { width: 40px; height: 40px; }
    .evtd-map-btn img { width: 18px; height: 18px; }
}

/* ---------- Programme ---------- */
.evtd-programme { display: flex; flex-direction: column; gap: 40px; }
.evtd-programme h2 { margin: 0; font-size: 40px; line-height: 48px; font-weight: 700; color: var(--hr-brown-500); }
.evtd-programme-day { display: flex; flex-direction: column; gap: 16px; }
.evtd-programme-day-label { font-size: 18px; font-weight: 700; color: var(--hr-brown-300); }
.evtd-programme-list { position: relative; display: flex; flex-direction: column; gap: 24px; }
/* Figma (node 40001286:71274) draws the double-diamond mark as one flattened
   asset with a fixed-length hairline baked in — fine for the 3-row mock it
   was designed against, but a day with only 1 schedule row rendered a line
   that ran on past the actual list and into the NEXT day's diamond. Split
   the fixed-size diamond glyph (cropped from the same asset, bottom portion
   — the two diamonds are vertically symmetric so cropping vs. flipping
   looks identical) from a plain CSS line that stretches with `flex:1 1 auto`
   to whatever height .evtd-programme-list actually is for that day, so it
   always stops exactly at that day's last row. Bleeds into the section's
   own side padding so it never overlaps the row cards. Hidden below 1200px
   where there's no side padding left to bleed into. */
.evtd-programme-decor {
    position: absolute;
    z-index: -1;
    inset-inline-start: -84px;
    top: 0;
    bottom: 0;
    width: 64px;
    display: flex;
    flex-direction: column;
    align-items: center;
    opacity: .1;
    pointer-events: none;
}
/* 116px is the full two-diamond glyph and is NOT capped against the list's own
   height. It used to be min(116px, 100% - 24px), which kept the line alive on a
   short day but did it by shrinking this box - and since the box crops the
   glyph, a single-row day (list ~77px tall) shrank it to ~53px and cut the
   SECOND diamond off, leaving one diamond and a stub. The mark has to read the
   same at any row count, so the height is fixed here and the room for it is
   made by .evtd-programme-list's min-height instead. */
.evtd-programme-decor-diamonds { flex-shrink: 0; width: 100%; height: 116px; overflow: hidden; }
.evtd-programme-decor-diamonds img { display: block; width: 100%; height: 263px; position: relative; top: -147px; }
.evtd-programme-decor-line { flex: 1 1 auto; width: 1px; background: var(--hr-cream-700, #b1afa5); }
.evtd-programme-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 24px 34px 24px 24px;
    border-radius: 20px;
    border: 1px solid #fff;
    background: linear-gradient(to top, rgba(255, 255, 255, .45), rgba(255, 255, 255, .6) 76%, rgba(255, 255, 255, .6));
    -webkit-backdrop-filter: blur(53.55px);
    backdrop-filter: blur(53.55px);
    box-shadow: inset 0 4px 6.1px rgba(255, 255, 255, .23);
}
/* Bordered/two-tone diamond, matching the same mark already used for
   .podd-guest-mark (podcasts-detail-revamp.css) elsewhere on the site: an
   outer ring plus a smaller solid diamond inset inside it. */
.evtd-programme-marker {
    position: relative;
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    border: 1.5px solid var(--hr-purple-500, #8e3b78);
    transform: rotate(45deg);
}
.evtd-programme-marker::after { content: ""; position: absolute; inset: 4px; background: var(--hr-purple-500, #8e3b78); }
.evtd-programme-time { flex-shrink: 0; font-size: 24px; font-weight: 700; color: var(--hr-green-500); }
.evtd-programme-title { font-size: 24px; font-weight: 700; color: var(--hr-brown-700); }
/* Floor that guarantees the decor always has room for the whole mark: 116px of
   diamonds plus the 24px minimum of connecting line the original cap was trying
   to preserve. On a one- or two-row day this leaves empty space below the last
   row, which is the intended trade - the mark stays complete rather than being
   trimmed to fit. Scoped to the same breakpoint the decor is visible at, so it
   adds no dead space below 1200px where the decor is hidden. */
@media (min-width: 1200px) {
    .evtd-programme-list { min-height: 140px; }
}
@media (max-width: 1199.98px) {
    .evtd-programme-decor { display: none; }
}

/* ---------- Gallery / Video / Speakers (existing features, restyled to the new tokens) ---------- */
.evtd-gallery-head { display: flex; align-items: center; gap: 16px; margin-bottom: 40px; }
.evtd-gallery-head h2 { margin: 0; font-size: 40px; line-height: 48px; font-weight: 700; color: var(--hr-brown-500); }
.evtd-marquee-wrapper { overflow: hidden; }
.evtd-marquee-inner { display: flex; gap: 24px; }
.evtd-marquee-inner + .evtd-marquee-inner { margin-top: 24px; }
.evtd-marquee-item img { display: block; height: 240px; width: auto; border-radius: 20px; object-fit: cover; }

/* Figma node 40002817:89730 places this at x=0, w=1920 - edge to edge, no page
   gutter, no 1600px inner cap and no corner radius. It is a plain sibling
   between sections rather than an .evtd-section, so its box already spans the
   viewport's client width; overflow:hidden guards against a video whose
   intrinsic ratio would otherwise push the document wider than that.

   The old .evtd-video-wrap rule is kept below it: the class no longer appears
   in events/show.blade.php, but it is cheap to leave for any other page that
   still boxes a video this way, and removing it is not this change's business. */
.evtd-video-bleed {
    position: relative;
    z-index: 1;
    display: block;
    overflow: hidden;
    /* Own stacking context so the play button's plus-lighter bloom composites
       against this block rather than the page. */
    isolation: isolate;
    /* The still, painted behind the <video> - see the note on --evtd-video-poster
       in events/show.blade.php. The brown underneath covers the case where even
       the fallback asset is unavailable, so the block is never a blank field. */
    background: var(--hr-brown-700) var(--evtd-video-poster, none) center / cover no-repeat;
}
/* Figma's "overlay": transparent to solid black over the bottom 56% of the
   frame, starting at the play button's own centre line (263.71 of 600). It
   carries the title, description and duration chip below it. */
.evtd-video-scrim {
    position: absolute;
    inset: 44% 0 0;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 100%);
    pointer-events: none;
}
/* Figma's Button (node 40002817:89740), built to the SAME recipe as the video
   pages' own play circles (.vid-card-play / .vid-feature-play) rather than an
   approximation of it. Three things differed on the first pass:

   - border: transparent, not a literal 1.5px white. The design's stroke is a
     3-stop gradient, and that is the shared masked rim on ::after in
     layout-revamp.css - inset:-1.5px against the padding box, exactly where a
     1.5px border sits. --hr-ring-start/-mid carry this node's own leading and
     middle stops (white 30%, #65686F 39%) in place of the .1/.3 defaults. A
     flat white stroke read harder and brighter than the design.
   - the glyph is solar:play-bold at its native 19x20 with a 1.5px optical
     nudge, not video-play-icon.svg stretched to 24x24.
   - isolation:isolate, so the Ellipse 262 bloom composites against this fill.

   Centring stays on negative margins rather than the video pages'
   translate(-50%,-50%) - see the note below on why. */
/* Centred with negative margins rather than translate(-50%,-50%): `transform`
   is a single property, so ANY other rule that sets a transform on this element
   (a sitewide button:hover lift, for instance) replaces the centring outright
   and the button jumps 36px on hover - and if it jumps out from under the
   cursor it un-hovers, snaps back, re-hovers, and oscillates. Margins cannot be
   clobbered that way, and transition is pinned to the two properties that
   should actually animate so an inherited `transition: all` cannot animate
   layout. */
.evtd-video-play {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -36px 0 0 -36px;
    transition: background-color .2s ease, box-shadow .2s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    padding: 0;
    border-radius: 61px;
    background: var(--hr-yellow-500);
    border: 1.5px solid transparent;
    --hr-ring-start: rgba(255, 255, 255, .3);
    --hr-ring-mid: rgba(101, 104, 111, .39);
    box-shadow:
        0 4px 6.1px 0 rgba(255, 255, 255, .23) inset,
        2px 23px 14px 0 rgba(0, 0, 0, .02),
        1px 10px 10px 0 rgba(0, 0, 0, .03),
        0 3px 6px 0 rgba(0, 0, 0, .03);
    isolation: isolate;
    cursor: pointer;
}
.evtd-video-play img { width: 19px; height: 20px; transform: translateX(1.5px); }
/* Aligned to the page gutter, not the frame edge: Figma puts this row at
   x=160 with a 1600 width, i.e. on the same column as every other section. */
.evtd-video-overlay {
    position: absolute;
    inset-inline: 160px;
    bottom: 40px;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    pointer-events: none;
}
.evtd-video-copy { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.evtd-video-title { font-size: 32px; line-height: 40px; font-weight: 700; color: #f9f7ea; }
.evtd-video-desc { font-size: 16px; line-height: 24px; color: #f9f7ea; opacity: .7; }
/* The same chip the video cards carry: rgba(23,21,9,.8) at an 11.626px radius
   with the amber clock and 18px bold white text. */
.evtd-video-duration {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 15px;
    border-radius: 12px;
    background: rgba(23, 21, 9, .8);
    color: #fff;
    font-size: 18px;
    font-weight: 700;
    white-space: nowrap;
}
/* Once it is actually playing, the still's furniture would only sit in the
   way - the native controls take over (set in JS alongside this class). */
.evtd-video-bleed.is-playing .evtd-video-scrim,
.evtd-video-bleed.is-playing .evtd-video-play,
.evtd-video-bleed.is-playing .evtd-video-overlay { opacity: 0; visibility: hidden; }
@media (max-width: 991.98px) {
    .evtd-video-overlay { inset-inline: 40px; bottom: 28px; }
    .evtd-video-title { font-size: 24px; line-height: 32px; }
}
@media (max-width: 767.98px) {
    /* The desktop composition puts the play circle at the frame's centre and
       the copy over the bottom of the same frame. That only works while the
       frame is tall enough to hold both: at 375px the 16:9 crop is 211px and
       the copy block alone (20/28 title + 14/20 description + the 37px chip,
       plus its gaps) is ~149 of them, so the centred circle sat ON the
       description - the two are simply competing for the same 211px.

       On phones the block is laid out as a column instead: the poster/video
       fills the box through `position: absolute`, and the box's height comes
       from the furniture in flow - play circle, then the copy pinned to the
       bottom by `margin-top: auto`. Nothing is positioned against a
       percentage of a height that the content itself has to fit inside, so a
       longer title (or a narrower phone) grows the block rather than
       colliding inside it. */
    .evtd-video-bleed { display: flex; flex-direction: column; align-items: center; }
    /* Both the circle and the copy below are `relative`, not `static`: they
       are back in flow (so the desktop rule's negative-margin centring no
       longer applies - the margins here are plain spacing above and below the
       circle), but the video they sit on is absolutely positioned, and a
       positioned element paints over the backgrounds of non-positioned ones.
       Relative keeps them in the column's flow while z-index puts them back in
       front of the poster.

       `inset: auto` is then not redundant: the desktop rule's top/left:50% and
       the tablet rule's inset-inline:40px stay in effect under `relative`,
       where they read as an OFFSET from the flow position rather than a
       placement - left on, they shoved the circle 50% of the block to the
       right and the copy 40px past the frame's edge. */
    /* Layout only. Everything about how the circle LOOKS - the amber fill, the
       1.5px transparent border carrying layout-revamp.css's shared glass rim,
       and the four-layer shadow - stays exactly as the base rule sets it, which
       is the same recipe .vid-card-play uses on the videos page. Size stays 72px
       for the same reason: that page keeps its play circles at 72 across every
       breakpoint. */
    .evtd-video-play { position: relative; z-index: 1; inset: auto; margin: 48px 0 32px; }
    /* The copy carries its own gradient here rather than sitting on
       .evtd-video-scrim. The scrim starts at a percentage of the frame (44%),
       which lined up with the copy only while the frame was the old fixed
       crop: against the content-driven height the title landed 3px into the
       gradient's fully-transparent end and cream-on-bright-poster is
       unreadable. A background on the overlay is sized to the copy by
       definition, so it cannot drift out of register again. */
    .evtd-video-overlay {
        position: relative;
        z-index: 1;
        inset: auto;
        width: 100%;
        margin-top: auto;
        padding: 24px 16px 20px;
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
        background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .75) 45%, rgba(0, 0, 0, .92) 100%);
    }
    /* Would only stack a second, differently-registered gradient on top of
       that one. */
    .evtd-video-scrim { display: none; }
    .evtd-video-title { font-size: 20px; line-height: 28px; }
    .evtd-video-desc { font-size: 14px; line-height: 20px; }
}
/* aspect-ratio, NOT a vw height. Figma is 1920x600, and `height: 31.25vw` did
   reproduce that ratio - but vw resolves against the viewport INCLUDING the
   scrollbar, so the box's height depends on the page's own scroll state. Any
   nudge that adds or removes the scrollbar changes vw, which changes this
   height, which changes the page height, which can toggle the scrollbar again:
   a reflow oscillation that reads on screen as the whole block juddering.
   aspect-ratio derives the height from this element's own width instead, so it
   holds 1920:600 at every size with nothing to feed back on. */
.evtd-video-bleed video {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1920 / 600;
    object-fit: cover;
}
@media (max-width: 767.98px) {
    /* Must live HERE, after the rule above, not up with the rest of the phone
       block: both are (0,2,0) on `.evtd-video-bleed video`, so at equal
       specificity the later one wins and `height: auto` + the 1920/600 ratio
       would beat anything declared earlier.

       The phone crop is no longer a ratio at all. The column layout above
       gives the block its height from the furniture in flow, and the video
       stretches to whatever that comes to - which is what replaces the 16:9
       stand-in that used to be here (the 3.2:1 desktop frame is only 117px
       tall at 375px wide, too short for the poster to read as anything). */
    .evtd-video-bleed video {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        /* Height comes from `inset` now - the ratio would fight it. */
        aspect-ratio: auto;
    }
    /* That box is no longer the video's own 16:9, so `cover` would crop the
       sides off the picture once it is actually playing. Letterbox it against
       black for that state only; the poster still fills the frame. */
    .evtd-video-bleed.is-playing video { object-fit: contain; background: #000; }
}
.evtd-video-wrap video { width: 100%; border-radius: 24px; display: block; }

/* ---------- Related events (reuses .evt-grid / .evt-card from events-revamp.css) ---------- */
/* The teal sweep with its two diamonds closing the "You may also Like" section.

   body-corner-motif.svg (#338A81, native 300.078x175.676) - the same asset and
   the same treatment .evt-past-motif already uses to close the Events listing,
   which is itself .prd-body-motif's asset rotated. There it hangs from the
   workspace's top-end corner; both here and on the listing it is anchored to the
   section's bottom-start corner and rotated 180deg, so the sweep runs along the
   bottom edge with the two diamond points reaching up into the section.

   The section is already position:relative z-index:1, so the motif only needs
   z-index:0 to sit under .evtd-section-inner - the cards always paint over it.
   Responsive steps are the listing's, so the two pages shrink in step. */
.evtd-related-motif {
    position: absolute;
    z-index: 0;
    bottom: 0;
    inset-inline-start: 0;
    width: 300px;
    height: 176px;
    background: url("../images/press-releases-revamp/body-corner-motif.svg") no-repeat center / 100% 100%;
    transform: rotate(180deg);
    pointer-events: none;
}
/* The artwork is asymmetric, so it mirrors with the reading direction as well as
   rotating - same compound transform the listing carries. */
[dir="rtl"] .evtd-related-motif { transform: rotate(180deg) scaleX(-1); }
@media (max-width: 1199.98px) { .evtd-related-motif { width: 240px; height: 141px; } }
@media (max-width: 767.98px) { .evtd-related-motif { width: 84px; height: 49px; } }
/* Above the motif, so the cards and heading are never tinted by it. */
.evtd-related .evtd-section-inner { position: relative; z-index: 1; }
.evtd-related-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 48px; }
.evtd-related-head h2 { margin: 0; font-size: 40px; line-height: 48px; font-weight: 700; color: var(--hr-brown-500); }

/* ---------- Not-found state ---------- */
.evtd-empty {
    position: relative;
    z-index: 1;
    padding: 160px 160px 200px;
    max-width: 800px;
    margin-inline: auto;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
}
.evtd-empty h1 { font-size: 40px; font-weight: 700; color: var(--hr-brown-500); margin: 0; }
.evtd-empty p { font-size: 18px; line-height: 28px; color: var(--hr-brown-300); margin: 0; }

/* ---------- Responsive ---------- */
@media (max-width: 1439.98px) {
    .evtd-header { flex-direction: column; }
    /* .evtd-header-media's `flex: 1 1 0` is a row-axis (width) rule — in a
       column flex container flex-basis:0 applies to HEIGHT instead, and
       .evtd-header's align-items:flex-start means the column never stretches
       to fill the container's width on its own, so the image (and the
       stats row under it) shrank to an off-center sliver instead of running
       full width. Same bug/fix as .evtd-map below. */
    .evtd-header-media { flex: none; width: 100%; }
    /* .evtd-map's `flex: 1 1 0` is a row-axis (width) rule — in a column
       flex container flex-basis:0 applies to HEIGHT instead, collapsing the
       card to ~0px because there's no fixed-height parent for it to grow
       into. Reset it to a plain block sized by its own aspect-ratio. */
    .evtd-about-row { flex-direction: column; }
    .evtd-map { flex: none; width: 100%; }
}
@media (max-width: 1199.98px) {
    .evtd-hero,
    .evtd-header-wrap,
    .evtd-section,
    .evtd-divider { padding-inline: 40px; }
    .evtd-title { font-size: 48px; line-height: 56px; }
}
@media (max-width: 991.98px) {
    /* The hero's 256px is desktop clearance for the overlaid header. Down here
       that header is only ~64px tall, so a fixed height plus align-items:
       flex-end left ~96px of empty wash between it and the breadcrumb. Sized by
       its own content instead, with just enough top padding to clear the
       header - a smaller fixed height would still gap on a one-line breadcrumb
       and, worse, ride up under the header once a long title wraps to three.
       .evtd-hero-decor is a sibling, not a child, so it cannot follow that
       height and takes the two-line figure (88 + 72 + 24); it is a blend-mode
       overlay on a continuous wash, so its exact end is not a visible edge. */
    .evtd-hero { height: auto; min-height: 0; padding-top: 88px; }
    .evtd-hero-decor { height: 184px; }
    .evtd-header-wrap { padding-top: 60px; }
    .evtd-section { padding-block: 60px; }
    .evtd-stats { gap: 24px; }
}
@media (max-width: 767.98px) {
    .evtd-hero,
    .evtd-header-wrap,
    .evtd-section,
    .evtd-divider { padding-inline: 16px; }
    /* Icon ABOVE text, three across - ported from .smt-hero-stat's own mobile
       treatment in summit-revamp.css (Figma's 402px artboard turns that page's
       icon-beside-text rows into one across-the-width row of icon-above-text).

       This used to stack to a single column, because 3 columns of
       icon-BESIDE-text left only ~30px for copy after the 64px tile and
       overflow-wrap was splitting words letter by letter. Dropping the icon
       onto its own line is what actually fixes that: the text now gets the
       full third (~106px on a 375px screen) instead of third-minus-tile, so
       "September" and "Beginner" fit on one line and the row can stay three
       across as the design has it.

       Tile and type scale by the same ratios the Summit page uses between its
       desktop and mobile stats (tile x0.77, value x0.75, sub-label x0.7),
       applied to THIS page's own larger desktop values - 64/32/24/20 rather
       than the Summit's 52/28/20/16 - so it keeps its own visual identity
       (glass tile, brown text on cream) rather than inheriting the Summit's
       flat-white-on-photo treatment, which would be near-invisible here. The
       2:1 tile-to-icon ratio is preserved. */
    .evtd-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
    .evtd-stat { flex-direction: column; align-items: center; text-align: center; gap: 8px; }
    .evtd-stat-text { align-items: center; gap: 4px; }
    .evtd-stat-icon { width: 48px; height: 48px; border-radius: 8px; }
    .evtd-stat-icon img { width: 24px; height: 24px; }
    .evtd-stat-text strong { font-size: 18px; line-height: 24px; }
    .evtd-stat-text span { font-size: 14px; line-height: 20px; }
    .evtd-title { font-size: 34px; line-height: 42px; }
    .evtd-desc { font-size: 18px; line-height: 26px; }
    .evtd-about-copy h2,
    .evtd-programme h2,
    .evtd-gallery-head h2,
    .evtd-speakers-head h2,
    .evtd-related-head h2 { font-size: 28px; line-height: 36px; }
    .evtd-speakers-grid { grid-template-columns: 1fr; }
    /* 320 from 507, so the initials come down with the panel - the same ratio
       .blgd-cover-initials steps at (200 over a 600px cover). */
    .evtd-media { height: 320px; }
    .evtd-media-initials { font-size: 110px; }
    .evtd-programme-row { flex-wrap: wrap; padding: 20px; }
}

/* ==========================================================================
   Agenda + Speakers (Figma nodes 40002817:89741 and 40002817:89779)

   Ported from summit-revamp.css's .smt-agenda / .smt-speakers rather than
   included from them. The first attempt DID include the Summit page's own
   partials and loaded its stylesheet here, which looked right in a DOM check
   and was badly broken on screen: every one of those sections' 18
   `padding: 100px var(--smt-gutter)` declarations resolves against a variable
   declared ONLY on `.summit-revamp`, so on this page the custom property was
   empty, the whole padding shorthand was invalid at computed-value time and
   dropped, and both sections rendered flush to the viewport edge with their
   head buttons unstyled (those come from `.summit-revamp .hr-btn*`, which
   likewise never matched here).

   So the gutter is declared locally below, the two head buttons use this
   page's own .evtd-btn-ghost, and the sections carry no dependency on another
   page's root class.
   ========================================================================== */
.event-detail-revamp {
    /* Same two values .summit-revamp uses, and for the same reason: the header
       switches to its 160px container at exactly 992px, so these sections
       switch with it. Declared here so nothing depends on another page's root. */
    --evtd-gutter: 12px;
}
@media (min-width: 992px) {
    .event-detail-revamp { --evtd-gutter: 160px; }
}
.evtd-icon-mask {
    display: inline-block;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
    background-color: currentColor;
}
/* padding: 120px, Figma's own figure - the Agenda frame is 1920x784 with its
   content frame at y=120 h=544, so 120 above and 120 below. The ported value was
   100 (the Summit page's), which is why the section sat slightly tighter than
   the design at both ends. */
.evtd-agenda {
    position: relative;
    background: var(--hr-cream-500);
    /* Was 24px: .smt-agenda-inner's 1400px cap only starts creating real
       margins once the viewport clears ~1450px, so on every laptop width
       below that the content ran within 24px of the screen edges while wide
       monitors looked correct. See --smt-gutter for why this is now
       proportional rather than a fixed px value. */
    padding: 120px var(--evtd-gutter);
    overflow: hidden;
}
.evtd-agenda-inner { position: relative; z-index: 1; max-width: none; margin-inline: auto; }
/* Height tracks this section's OWN padding-top, which is what lines the two
   diamonds up with the first line of "Two Days of". The shape hangs from the
   section's top edge and its diamonds sit at the foot of it (y 108-200 of a
   208-tall viewBox), so the bottom edge is what lands beside the heading - and
   the heading starts exactly one padding-top down.
   Ported at the Annual Gathering's 100px, where that section's padding is also
   100px so the two agreed by accident; here the padding is 120px, which left the
   diamonds floating 20px above the title. Not a distortion either: the asset is
   preserveAspectRatio="none" and 316px wide, so its proportional height is
   113.7px - 120 is closer to that than the 100 it replaces. */
.evtd-agenda-corner-shape {
    position: absolute;
    top: 0;
    inset-inline-end: -40px;
    width: 316px;
    height: 120px;
    transform: scaleX(-1);
    pointer-events: none;
}
[dir="rtl"] .evtd-agenda-corner-shape { transform: none; }
.evtd-agenda-corner-shape-mobile { display: none; }
@media (max-width: 991.98px) {
    .evtd-agenda-corner-shape-mobile {
            display: block;
            position: absolute;
            top: 0;
            inset-inline-end: 0;
            width: 109px;
            height: 64px;
            /* 180deg, not a plain scaleY(-1). The source file draws the solid band
               along its BOTTOM edge, two diamonds spiking UP out of it at x~23/49,
               and the mass tapering to nothing at the RIGHT. The design needs all
               three inverted at once - solid edge against the hero above, diamonds
               hanging below, and the mass weighted toward the right - which is a
               rotation, not a mirror. Flipping only vertically fixed the first two
               but left the taper on the wrong side, so the shape read as twisted. */
            transform: rotate(180deg);
            pointer-events: none;
        }
    [dir="rtl"] .evtd-agenda-corner-shape-mobile { transform: scaleY(-1); }
}
@media (max-width: 991.98px) {
    .evtd-agenda-corner-shape { display: none; }
}
.evtd-agenda-head {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
    /* 80px: Figma's head row is h=112 at y=0 and the card row starts at y=192. */
    margin-bottom: 80px;
}
.evtd-agenda-head h2 { font-size: 40px; font-weight: 700; color: var(--hr-brown-500); margin: 0; }
/* The action belongs at the end of the row whether or not the heading is
   there. The <h2> is optional - it renders only when an agenda section title
   has been authored (see the partial) - and with `space-between` alone a lone
   button is a single flex item, which lands at the START. An auto inline-start
   margin pins it to the end in both cases, and stays correct under RTL. */
.evtd-agenda-head .evtd-btn-ghost { margin-inline-start: auto; }
/* The design breaks this heading before its highlighted words ("Two Days of" /
   "Ideas & Impact."). That used to be a <br> in the blade, but the title is
   admin-authored plain text now, so the break belongs here - on the accent
   span, the only part the markup still identifies. Mirrors the same rule on
   .smt-agenda-head in summit-revamp.css. */
.evtd-agenda-head h2 .hr-accent { display: block; }
.evtd-agenda-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 80px;
}
@media (max-width: 1399.98px) {
    .evtd-agenda-grid { gap: 56px; }
}
.evtd-agenda-card {
    flex: 1 1 340px;
    min-width: 0;
}
/* :last-child - the dashed rule, its padding and its margin exist to separate
   the head from the description below it. An agenda day with no description AND
   no schedule times (a real case: "Pre-Event Registration" here) renders the
   head alone, and all three then hung off the bottom of the card as ~50px of
   dead space plus a rule separating nothing. With the description absent the
   head IS the card's last child, so the separator collapses with it. */
.evtd-agenda-card-head:last-child {
    border-bottom: 0;
    padding-bottom: 0;
    margin-bottom: 0;
}
.evtd-agenda-card-head {
    border-bottom: 1px dashed var(--hr-brown-400);
    padding-bottom: 24px;
    margin-bottom: 24px;
}
.evtd-agenda-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: rgba(255,255,255,.4);
    border: 1px solid rgba(176,201,218,.3);
    border-radius: 56px;
    padding: 8px 8px 8px 12px;
    margin-bottom: 24px;
}
[dir="rtl"] .evtd-agenda-badge { padding: 8px 12px 8px 8px; }
.evtd-agenda-badge .evtd-icon-mask { width: 18px; height: 18px; color: var(--hr-blue-500); flex-shrink: 0; }
.evtd-agenda-badge span:not(.evtd-icon-mask) {
    background: var(--hr-blue-50);
    color: var(--hr-blue-500);
    border-radius: 56px;
    padding: 8px 16px;
    font-weight: 700;
    font-size: 14px;
}
.evtd-agenda-card-head h3 { font-size: 28px; font-weight: 700; color: var(--hr-brown-700); margin: 0 0 16px; }
.evtd-agenda-time {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 20px;
    color: var(--hr-brown-700);
}
.evtd-agenda-time .evtd-icon-mask { width: 20px; height: 20px; color: var(--hr-yellow-500); }
/* margin-bottom:0, not the ported 16px. The description is the LAST thing in
   the card, so that margin was 16px of dead space between the copy and the
   section's own padding - which then pushed the copy 24px clear of the corner
   motif instead of Figma's 8px (the description sits flush with the card row's
   bottom edge at y=352 of 352 there). The <=767 block already zeroed it for
   the same reason; it should never have differed by breakpoint. */
.evtd-agenda-desc { font-size: 18px; color: var(--hr-brown-400); line-height: 1.6; margin-bottom: 0; }

/* The agenda schedule editor can produce paragraphs, ordered/unordered lists,
   links and rules, and this field renders that HTML raw. app.css resets
   `li { list-style: none }` and `ul { padding: 0 }` sitewide, so a list from
   the editor would come out with no markers and no indent, and the 1rem bottom
   margin on p/ol/ul would hang extra space off the end of every description.
   Undone here, scoped. Mirrors the same block in agenda-detail-revamp.css -
   keep the three in step. */
.evtd-agenda-desc > :first-child { margin-top: 0; }
.evtd-agenda-desc > :last-child { margin-bottom: 0; }
.evtd-agenda-desc ol { list-style: decimal; }
.evtd-agenda-desc ul { list-style: disc; }
/* padding-inline-start so the markers sit correctly in Arabic; 24px normalises
   ol (which keeps app.css's 2rem) and ul (reset to 0) to one indent. */
.evtd-agenda-desc ol,
.evtd-agenda-desc ul { padding-inline-start: 24px; margin-block: 0 8px; }
.evtd-agenda-desc li { list-style: inherit; }
.evtd-agenda-card-title {
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
}
.evtd-agenda-card-title:hover, .evtd-agenda-card-title:focus-visible { color: var(--hr-blue-500); text-decoration: underline; }
.evtd-speakers { background: var(--hr-brown-500); padding: 100px var(--evtd-gutter); }
/* Applied when there is no "You may also Like" section after this one. The
   gold .evtd-divider is rendered only alongside that grid, so without it this
   dark section butted straight against the dark footer with no seam at all.

   inset-inline:0, edge to edge. It was var(--evtd-gutter) so the rule would
   line up with the content column above it, but a seam between two full-bleed
   dark bands reads as a stop short of the screen rather than as alignment -
   most visibly on wide monitors, where the gutter is at its 160px ceiling.
   .evtd-hero::after, the same cream hairline at the other end of this page,
   already runs left:0 / right:0, so this now matches it. */
.evtd-speakers-ruled { position: relative; }
.evtd-speakers-ruled::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 1px;
    background: rgba(249, 247, 234, .35);
}
.evtd-speakers-inner { max-width: none; margin-inline: auto; }
.evtd-speakers-head {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 64px;
}
.evtd-speakers-head h2 { font-size: 40px; font-weight: 700; color: var(--hr-cream-500); margin: 0 0 12px; }
.evtd-speakers-head p { font-size: 20px; color: var(--hr-brown-300); margin: 0; max-width: 700px; }
.evtd-speakers-head-actions { display: flex; align-items: center; gap: 12px; margin-inline-start: auto; }
[dir="rtl"] .evtd-speakers-head-actions a img { transform: scaleX(-1); }
.evtd-speakers-swiper { width: 100%; overflow: hidden; }
.evtd-speaker-card {
    position: relative;
    width: 100%;
    aspect-ratio: 382 / 507;
    border-radius: 30px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 24px;
    isolation: isolate;
}
.evtd-speaker-card-bg {
    position: absolute;
    inset: 0;
    background-size: contain;
    background-position: bottom center;
    background-repeat: no-repeat;
}
.evtd-speaker-card-bg-placeholder {
    background-size: 140px !important;
    background-repeat: no-repeat;
    background-position: center !important;
}
.evtd-speaker-card-pattern {
    position: absolute;
    top: -3.014%;
    left: -54.503%;
    width: 145.923%;
    height: 47.531%;
    background: url("../images/summit-revamp/speaker-card-pattern.svg") no-repeat center / contain;
    transform: rotate(90deg) scaleY(-1);
    /* Sits BEHIND the speaker photo, as in Figma — visible around the
       cut-out subject rather than behind an opaque photo rectangle. */
    pointer-events: none;
}
.evtd-speaker-card-pattern-alt {
    top: -27.117%;
    left: -67.039%;
    width: 234.077%;
    height: 76.245%;
    transform: rotate(-179.43deg) scaleY(-1);
}
.evtd-speaker-card-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity .25s ease;
    pointer-events: none;
}
.evtd-speaker-card:hover .evtd-speaker-card-video, .evtd-speaker-card:focus-within .evtd-speaker-card-video { opacity: 1; }
/* --evtd-speaker-expand, not the --smt- name the port carried over: that
   variable is declared nowhere (on either page), so every reference to it was
   already falling through to the 1.48 default. Renaming it removes the last
   dangling dependency on another page's namespace - the same class of mistake
   that silently killed this section's padding and its arrow rim. */
.evtd-speakers-swiper { --evtd-speaker-expand: 1.48; }
.evtd-speakers-swiper .swiper-slide { transition: width .35s ease; }
.evtd-speaker-card { transition: aspect-ratio .35s ease; }
/* Hover expansion has to be paid for by the other cards. Swiper fixes each
   slide's width inline at init and never recalculates it, and slidesPerView
   makes the slides fill the track exactly - so widening one by 48% pushed the
   row 132px past the track, where overflow:hidden cut it off: hovering the
   first or second card clipped the last one, and hovering the last card sliced
   the very card being pointed at in half. Shrinking the siblings by the same
   total keeps the row the same width (1.48 + 2 x 0.76 = 3 columns, and
   1.48 + 3 x 0.84 = 4), so nothing ever leaves the track and Swiper's own
   geometry stays valid. Each card's aspect-ratio is scaled by its own width
   factor so the row height holds steady while the widths animate. */
@media (min-width: 992px) and (max-width: 1299.98px) {
    .evtd-speakers-swiper { --evtd-spk-unit: calc((100% - 48px) / 3); --evtd-spk-shrink: .76; }
}
@media (min-width: 1300px) {
    .evtd-speakers-swiper { --evtd-spk-unit: calc((100% - 72px) / 4); --evtd-spk-shrink: .84; }
}
@media (min-width: 992px) {
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:hover) > .swiper-slide,
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:focus-within) > .swiper-slide {
            width: calc(var(--evtd-spk-unit) * var(--evtd-spk-shrink)) !important;
        }
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:hover) > .swiper-slide:has(.evtd-speaker-card-has-video:hover),
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:focus-within) > .swiper-slide:has(.evtd-speaker-card-has-video:focus-within) {
            width: calc(var(--evtd-spk-unit) * var(--evtd-speaker-expand, 1.48)) !important;
        }
    /* Shrunken siblings keep the row's height ... */
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:hover) .evtd-speaker-card,
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:focus-within) .evtd-speaker-card {
            aspect-ratio: calc(382 * var(--evtd-spk-shrink)) / 507;
        }
    /* ... and so does the expanded one. Needs the wrapper ancestor too, or the
       sibling rule above outranks it and flattens the hovered card. */
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:hover) .evtd-speaker-card-has-video:hover,
    .evtd-speakers-swiper .swiper-wrapper:has(.evtd-speaker-card-has-video:focus-within) .evtd-speaker-card-has-video:focus-within {
            aspect-ratio: calc(382 * var(--evtd-speaker-expand, 1.48)) / 507;
        }
    .evtd-speaker-card-has-video:hover .evtd-speaker-card-scrim, .evtd-speaker-card-has-video:focus-within .evtd-speaker-card-scrim, .evtd-speaker-card-has-video:hover .evtd-speaker-card-body > div, .evtd-speaker-card-has-video:focus-within .evtd-speaker-card-body > div {
            opacity: 0;
            transition: opacity .25s ease;
        }
}
.evtd-speaker-card-scrim {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 56.34%;
    background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,.65) 100%);
}
.evtd-speaker-card-body {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    color: var(--hr-cream-500);
}
.evtd-speaker-card-body > div { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.evtd-speaker-card-body strong { display: block; font-size: 24px; line-height: 32px; font-weight: 700; }
.evtd-speaker-card-body span { display: block; font-size: 20px; line-height: 28px; font-weight: 400; }
.evtd-speaker-card-location { font-weight: 700 !important; }
.evtd-speaker-card-link {
    position: absolute;
    inset: 0;
    z-index: 1;
}
.evtd-speaker-card-arrow {
    flex-shrink: 0;
    z-index: 2;
    width: 56px;
    height: 56px;
    border-radius: 61px;
    border: 1.5px solid transparent;
    background: rgba(255,255,255,.2);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow:
        inset 0 4px 6.1px rgba(255,255,255,.23),
        7px 63px 18px rgba(0,0,0,0),
        4px 40px 16px rgba(0,0,0,0),
        2px 23px 14px rgba(0,0,0,.02),
        1px 10px 10px rgba(0,0,0,.03),
        0 3px 6px rgba(0,0,0,.03);
    transition: background-color .2s ease, transform .2s ease;
}
.evtd-speaker-card-arrow:hover { background: rgba(255,255,255,.35); }
.evtd-speaker-card-arrow img { width: 24px; height: 24px; }
[dir="rtl"] .evtd-speaker-card-arrow img { transform: scaleX(-1); }
.evtd-speaker-card-arrow { transition: opacity .25s ease, transform .2s ease; }
.evtd-speaker-card-has-video:hover .evtd-speaker-card-arrow, .evtd-speaker-card-has-video:focus-within .evtd-speaker-card-arrow { opacity: 0; }
.evtd-speaker-card-has-video .evtd-speaker-card-arrow:focus-visible { opacity: 1; }
@media (max-width: 767.98px) {
    .evtd-agenda, .evtd-speakers { padding: 60px var(--evtd-gutter); }
    .evtd-speakers-head { margin-bottom: 32px; }
    .evtd-agenda-head h2 { font-size: 28px; }
    .evtd-agenda-card-head h3 { font-size: 20px; line-height: 28px; margin-bottom: 8px; }
    .evtd-agenda-time { font-size: 16px; }
    .evtd-agenda-time .evtd-icon-mask { width: 16px; height: 16px; }
    .evtd-agenda-desc { font-size: 16px; line-height: 24px; margin-bottom: 0; }
    .evtd-agenda-grid { gap: 16px; }
    .evtd-agenda-card {
            flex: 1 1 100%;
            background: rgba(255,255,255,.6);
            border-radius: 16px;
            padding: 20px;
        }
    .evtd-agenda-card-head { padding-bottom: 16px; margin-bottom: 16px; }
    .evtd-agenda-badge { margin-bottom: 16px; gap: 4px; padding: 4px 4px 4px 8px; }
    [dir="rtl"] .evtd-agenda-badge { padding: 4px 8px 4px 4px; }
    .evtd-agenda-badge .evtd-icon-mask { width: 16px; height: 16px; }
    .evtd-agenda-badge span:not(.evtd-icon-mask) { padding: 8px 12px; font-size: 12px; }
    /* display:contents dissolves the head so its h2 and its button can be
       ordered around .evtd-agenda-grid, which is their uncle rather than their
       sibling. Every one of the four children then needs an explicit order:
       whatever is left at the default 0 sorts FIRST. The button had no rule at
       all - the port dropped it, because the Summit page states it as
       `.smt-agenda-head .hr-btn-ghost-dark` and this page's copy filtered out
       every `hr-btn` selector on the way over - so it sat above the heading and,
       with the column's default align-items:stretch, spanned the full width.
       align-self:center returns it to its content width. */
    .evtd-agenda-inner { display: flex; flex-direction: column; }
    .evtd-agenda-head { display: contents; }
    .evtd-agenda-head h2 { order: 1; text-align: center; margin-bottom: 32px; }
    .evtd-agenda-grid { order: 2; }
    .evtd-agenda-head .evtd-btn-ghost { order: 3; align-self: center; margin-top: 40px; }
}
@media (max-width: 767.98px) {
    .smt-stats-head, /* :not() matters - .evtd-speakers-head-actions is also a direct div child, and ".evtd-speakers-head > div" (class+type) outranks its own single-class
           selector, so without this the actions block inherits the copy's centring
           AND its order:1, landing back above the slider. */
        .evtd-speakers-head > div:not(.evtd-speakers-head-actions), .smt-performance-head-copy, .smt-attend-copy, .smt-community-head {
            text-align: center;
            align-items: center;
        }
    .smt-stats-head h2, .evtd-speakers-head h2, .smt-performance-head-copy h2, .smt-attend-copy h2, .smt-community-head h2 {
            font-size: 24px;
            line-height: 32px;
            margin: 0 0 16px;
        }
    .smt-stats-head p, .evtd-speakers-head p, .smt-performance-head-copy p, .smt-attend-copy p {
            font-size: 16px;
            line-height: 24px;
            margin: 0;
            max-width: none;
        }
    .evtd-speakers-inner { display: flex; flex-direction: column; }
    .evtd-speakers-head { display: contents; }
    .evtd-speakers-head > div:not(.evtd-speakers-head-actions) { order: 1; margin-bottom: 32px; }
    .evtd-speakers-swiper { order: 2; }
    .evtd-speakers-head-actions {
            order: 3;
            justify-content: center;
            margin: 40px 0 0;
            margin-inline-start: 0;
        }
    .evtd-speakers-swiper, .smt-performance-swiper, .smt-attend-swiper, .smt-community-swiper {
            min-width: 0;
            width: 100%;
        }
}

/* The bottom-start corner motif (Figma node 40002817:89741 carries two Intersect
   vectors - top-end 300x176 and bottom-start 255x112). The Summit page dropped
   its copy because it collided with the stats section's own artwork at the
   seam; nothing follows this section on the Event page, so it is drawn here.
   agenda-corner-bottom.svg was already in the repo, just unreferenced. */
/* Figma node 40004073:54701, exported at its native 254.66x111.564: two
   touching diamonds sitting on a shallow hill, flush to this section's
   bottom-start corner.

   Two earlier passes got this wrong and both are worth naming. The first reused
   summit-revamp/agenda-corner-bottom.svg forced to 255x112; that asset is
   PORTRAIT (148.692x185.174) and declares preserveAspectRatio="none", so naming
   both a width and a height stretched the dome flat and squashed its diamond.
   The second kept that asset's ratio and cropped it instead - undistorted, but
   still the wrong shape, because the Annual Gathering asset carries a SINGLE
   diamond where this corner has two. No sizing of that file can produce this
   design; it needed its own export. The aspect ratio below matches the asset,
   so nothing is stretched and nothing is cropped. */
.evtd-agenda-corner-bottom {
    position: absolute;
    bottom: 0;
    inset-inline-start: 0;
    width: 255px;
    height: auto;
    aspect-ratio: 254.66 / 111.564;
    pointer-events: none;
}
/* inset-inline-start moves it to the opposite corner in RTL; the artwork is
   asymmetric (the hill falls away to one side only), so it mirrors with it. */
[dir="rtl"] .evtd-agenda-corner-bottom { transform: scaleX(-1); }
/* Scaled on phones, not hidden. "Both corners hide" was never true: the top one
   swaps to its own mobile export (.evtd-agenda-corner-shape-mobile, 109x64) and
   keeps its place, so hiding this one left the frame decorated at the top-end
   corner and bare at the bottom-start one.

   There is no separate mobile export of this shape, so it is the same file at
   64px tall - the height Figma gives the mobile top corner, which keeps the two
   matched the way they are on desktop (100 vs 111.5). Only the width is named;
   the aspect-ratio above derives the height from it, so the hill and its two
   diamonds scale without stretching (the whole point of that ratio). */
@media (max-width: 991.98px) {
    .evtd-agenda-corner-bottom { width: 146px; }
}

/* ---------- Moments (Figma node 40002817:89792, "Gallery") ----------
   A bento of the event's own gallery photos on the cream board, with the head
   row and its two scroll buttons above it. Numbers below are the artboard's:
   120px block padding, 80px from the head to the track, a 565px track, and
   18.692px used for BOTH the gaps and the photo radius - that odd figure is
   Figma's own, and it is one value, not a coincidence of two. */
/* Block padding only. The inline gutter moves onto the head wrapper so the
   TRACK can run edge to edge: the artboard's bento-container is w-full while the
   head row beside it is a fixed 1600, which is what cuts the photos off at both
   sides of the screen. Done structurally - the track simply is not inside
   anything that caps or pads it - rather than with a 100vw bleed, because 100vw
   counts the vertical scrollbar and would push the page into a horizontal
   scroll (the same trap noted on .abt-* in about-revamp.css). */
/* Same single cream as the agenda above it and the page behind it: at
   cream-400 this section stepped a shade lighter, which put a visible seam on
   the gold rule between the two. */
.evtd-moments { background: var(--hr-cream-500); padding: 120px 0; display: flex; flex-direction: column; gap: 80px; }
.evtd-moments-head-wrap { padding-inline: var(--evtd-gutter); }
.evtd-moments-head {
    max-width: 1600px;
    margin-inline: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
}
.evtd-moments-copy { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
/* Headings/H3/Bold - 48/56 - against brown-900, which is a step darker than the
   brown-500 the other section headings on this page use; the artboard sets this
   one on the cream board rather than over artwork. */
.evtd-moments-copy h2 { margin: 0; font-size: 48px; line-height: 56px; font-weight: 700; color: var(--hr-brown-900); }
/* Body/Body Large/Regular - 24/32. */
.evtd-moments-copy p { margin: 0; font-size: 24px; line-height: 32px; color: var(--hr-brown-300); }
.evtd-moments-nav { display: flex; align-items: center; gap: 20px; flex-shrink: 0; }
/* The same glass pill as .evtd-speaker-card-arrow further up this file - same
   56px box (16px of padding around a 24px glyph), same 61px radius, same
   five-layer ambient stack under an inset white highlight. Restated rather than
   sharing a class because that one carries card-hover behaviour these must not
   inherit. The 1.5px rim is the artboard's own rgba(255,255,255,.2), where the
   speaker arrow leaves it transparent. */
/* The home page's Memories filmstrip buttons (.hr-memories-filmstrip
   .hr-icon-btn in home-revamp.css): a 56px circle on a .2 white fill with that
   section's OWN shadow treatment - a single soft 0 4px 14px drop over a faint
   dark rim - rather than the inset-highlight stack the other pills carry.

   The GLASS is not in these declarations. It is the shared masked ring in
   layout-revamp.css (BIL-710): an ::after at inset -1.5px painting a 3-stop
   gradient rim, plus --hr-ring-start at white 20% for icon circles instead of
   the 10% default. .evtd-moments-arrow is joined to both of those selector
   lists there, which is why this rule only needs position:relative, for the
   ring to hang on. Styling the circle here WITHOUT joining those lists is what
   made the first pass read as a flat white disc.

   Verified against the home page by diffing computed styles: identical on box,
   radius, border, shadow, ring gradient, ring inset/padding and glyph filter.
   One deliberate difference - the home rule's fill is rgba(225,255,255,.2),
   whose 225 red channel looks like a slip for 255; this uses a true white. At
   .2 alpha the two differ by ~6/255 in a single channel and are
   indistinguishable, so the typo is not carried across. */
.evtd-moments-arrow {
    flex-shrink: 0;
    /* For the shared glass ring: it is an absolutely-positioned ::after at
       inset -1.5px, so it needs a positioned ancestor to land on the border
       box. Set here rather than in layout-revamp.css's position:relative list
       because this button is not otherwise positioned. */
    position: relative;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 1.5px solid rgba(27, 25, 12, .08);
    background: rgba(255, 255, 255, .2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(27, 25, 12, .06);
    transition: background-color .2s ease;
}
.evtd-moments-arrow:hover { background: rgba(255, 255, 255, .55); }
/* Nothing to scroll, so no controls. Set from JS (see the partial) because
   whether the track overflows depends on the photo count AND the viewport, and
   CSS cannot ask that question. Kept as a class on the section rather than an
   inline style so the rule stays visible here. */
.evtd-moments.is-static .evtd-moments-nav { display: none; }
.evtd-moments-arrow img { width: 24px; height: 24px; display: block; }
/* Not cosmetic - required. These are the same two exported SVGs the Memories
   filmstrip uses, and they carry baked-in strokes from their Figma context:
   the LEFT arrow is near-black and the RIGHT one near-white. Left as they are,
   the right arrow is invisible on a light button. Memories normalises both to
   black with exactly this filter; same asset, same fix. */
.evtd-moments-arrow img { filter: brightness(0); }
/* The glyphs are direction-specific assets (icon-arrow-left / -right), so RTL
   swaps which way each points rather than mirroring the pair - the buttons keep
   their order and "previous" still sits on the leading edge. */
[dir="rtl"] .evtd-moments-arrow img { transform: scaleX(-1); }

/* The track scrolls rather than wrapping: the artboard runs four columns of
   ~520 plus gaps against a 1600 board, so it is over-wide by design and the
   head's two buttons are what move it. */
.evtd-moments-track {
    display: flex;
    /* `safe center`, not plain `center`. When there are too few photos to fill
       the width the columns sit centred on the page, which is what the section
       should look like with a short gallery. Plain `center` would do that too,
       but once the content DOES overflow it centres the overflow as well and
       puts the first column off the start edge where no amount of scrolling can
       reach it. The `safe` keyword says: centre while it fits, fall back to
       start alignment the moment it would overflow. */
    justify-content: safe center;
    gap: 18.692px;
    height: 565px;
    overflow-x: auto;
    /* NO scroll-snap here, and that is a trade rather than an oversight.
       Snapping and a smooth programmatic scroll are mutually exclusive on this
       element in Chromium: measured with the tab actually rendering, a
       scrollBy({behavior:'smooth'}) animates and lands on the step with
       scroll-snap-type:none, and does not move at all under EITHER `x mandatory`
       or `x proximity`. The buttons are the primary control and the design asks
       for a smooth glide, so smooth wins.

       Nothing is lost by dropping it: the step the buttons scroll by is exactly
       one column plus one gap, so every click still comes to rest on a column
       edge. Only a free touch-swipe can now stop mid-photo, which is ordinary
       carousel behaviour.

       No `scroll-behavior: smooth` either - the buttons pass behavior:'smooth'
       themselves, which keeps the animation on the button-driven nudge instead
       of forcing it on every scroll the browser performs on this element. */
    /* The row is meant to run past the edge, so a persistent bar is just noise -
       same treatment as the filter scrollers elsewhere in the revamp. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.evtd-moments-track::-webkit-scrollbar { display: none; }
.evtd-moments-track:focus-visible { outline: 2px solid var(--hr-yellow-500); outline-offset: 4px; }
.evtd-moments-col {
    flex: 0 0 520px;
    display: flex;
    flex-direction: column;
    gap: 18.692px;
    height: 100%;
}
/* The 2-up row inside a split column. Both halves and the wide photo below take
   an equal share of the column's height, which is what makes the three-photo
   column read as the same rhythm as the single tall one beside it. */
.evtd-moments-pair { display: flex; gap: 18.692px; flex: 1 1 0; min-height: 0; }
.evtd-moments-pair .evtd-moments-photo { flex: 1 1 0; min-width: 0; }
/* split-bottom is split-top upside down. Ordered here rather than branching the
   markup, so the partial emits one shape and only the CSS knows the difference. */
.evtd-moments-col-split-bottom .evtd-moments-pair { order: 2; }
.evtd-moments-col-split-bottom .evtd-moments-photo-wide { order: 1; }
.evtd-moments-photo {
    flex: 1 1 0;
    min-height: 0;
    margin: 0;
    border-radius: 18.692px;
    overflow: hidden;
    background: var(--hr-brown-300);
}
/* The whole cell is the button that opens the lightbox. Stripped to nothing and
   sized 100%/100% so it is layout-invisible - the bento's cells are fixed
   shapes driven by .evtd-moments-photo's flex, and a default-styled <button>
   between the figure and its img would put its own box, padding and border in
   the middle of that.
   A real <button> rather than a click handler on the figure: it is focusable,
   Enter and Space open it, and it carries the aria-label. */
.evtd-moments-open {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    /* The cell already clips to its 18.692px radius; matching it here keeps the
       focus ring on the same curve. */
    border-radius: inherit;
}
.evtd-moments-open:focus-visible { outline: 2px solid var(--hr-yellow-500); outline-offset: -2px; }
/* object-fit:cover with both dimensions pinned: the gallery takes whatever
   aspect ratio an admin uploads, and the bento's cells are fixed shapes. */
.evtd-moments-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 1199.98px) {
    .evtd-moments-copy h2 { font-size: 40px; line-height: 48px; }
    .evtd-moments-copy p { font-size: 20px; line-height: 28px; }
    .evtd-moments-track { height: 470px; }
    .evtd-moments-col { flex-basis: 430px; }
}
@media (max-width: 991.98px) {
    /* padding-block only - an inline value here would put the gutter back on
       the section and un-bleed the track. */
    .evtd-moments { padding-block: 80px; gap: 48px; }
    .evtd-moments-track { height: 400px; }
    .evtd-moments-col { flex-basis: 360px; }
}
@media (max-width: 767.98px) {
    .evtd-moments { padding-block: 60px; gap: 32px; }
    /* The head stacks and the buttons drop: at this width the track is barely
       wider than one column, so a swipe is the natural control and two 56px
       pills would take a third of the row to duplicate it. */
    .evtd-moments-head { flex-direction: column; align-items: flex-start; gap: 16px; }
    .evtd-moments-nav { display: none; }
    .evtd-moments-copy h2 { font-size: 24px; line-height: 32px; }
    .evtd-moments-copy p { font-size: 16px; line-height: 24px; }
    .evtd-moments-track { height: 300px; gap: 12px; }
    .evtd-moments-col { flex-basis: 260px; gap: 12px; }
    .evtd-moments-pair { gap: 12px; }
    .evtd-moments-photo { border-radius: 12px; }

    /* One breadcrumb size site-wide on the phone, taken from the Events
       listing (.evt-breadcrumb in events-revamp.css): 12px type, 8px gaps,
       a 12px separator. This page had no phone step at all. */
    .evtd-breadcrumb { font-size: 12px; gap: 8px; }
    .evtd-breadcrumb-sep { height: 12px; }
}

/* ==========================================================================
   Optional section headings

   Every section heading on this page is admin-authored with no default behind
   it (Event::SECTION_HEADINGS is all null), so a section can legitimately
   render with no heading at all. The SECTION still shows either way - only the
   heading goes - which leaves two rows holding nothing but their own spacing.
   Collapsing them keeps that space from reading as a gap.

   :has() rather than :empty, because both wrappers still contain an element
   (the speakers row an inner div, the moments column whitespace), so :empty
   would never match. Both are already used elsewhere in this stylesheet.
   ========================================================================== */
.evtd-speakers-head:not(:has(h2)) { display: none; }
.evtd-moments-copy:not(:has(h2, p)) { display: none; }

/* ---------- Moments lightbox ----------
   The Memories & Stories photo lightbox, restated here under an evtd- prefix
   rather than by loading that page's stylesheet - the same convention the
   button primitives above follow, and the reason .vidd-btn-ghost and friends
   are re-declared per page. .mns-modal / .mns-photo-* in
   memories-stories-revamp.css is the original; the two are the same dialog and
   should be changed together. Worth extracting into layout-revamp.css if a
   third page needs it.

   Only the PHOTO half is ported. The memories page's shell also serves a video
   dialog; this section is a gallery, so .mns-modal-video has no counterpart and
   is not carried over.

   Dark rather than the page's cream: the stage is a photo or a video frame, and
   a cream surround throws its own colour back into the image. The header,
   footer and rims are cream-tinted whites so the shell still reads as this
   site's and not as a generic player chrome. */
.evtd-lb .modal-dialog {
    max-width: 1000px;
    width: calc(100% - 32px);
    margin-inline: auto;
}
.evtd-lb .modal-content {
    background: #14130c;
    border: 1px solid rgba(249, 247, 234, .14);
    border-radius: 24px;
    overflow: hidden;
    color: var(--hr-cream-500);
    /* Deeper than the site's ambient button ramp: this sits over a dimmed page
       and needs to read as lifted off it, not resting on it. */
    box-shadow: 0 32px 80px rgba(0, 0, 0, .55), 0 4px 12px rgba(0, 0, 0, .35);
}
.evtd-lb .modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 24px;
    border-bottom: 1px solid rgba(249, 247, 234, .12);
}
.evtd-lb-heading { min-width: 0; }
/* Says which kind of item is open — "Video", or the photo count — above the
   title, so the title itself never has to carry that. */
.evtd-lb-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 700;
    line-height: 16px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--hr-yellow-400);
}
.evtd-lb-eyebrow img { display: block; flex-shrink: 0; }
/* One line with an ellipsis: these captions are admin-authored and unbounded,
   and a wrapped title would push the stage down and reflow the dialog. */
.evtd-lb-title {
    margin: 0;
    font-size: 22px;
    line-height: 30px;
    font-weight: 700;
    color: var(--hr-cream-500);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Hand-rolled rather than Bootstrap's .btn-close: that one paints a dark SVG
   cross, invisible on this surface, and .custom-close (app.css) hard-codes a
   white FILLED circle that reads as a bright blob against the dark header. */
.evtd-lb-close {
    position: relative;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid rgba(249, 247, 234, .18);
    border-radius: 50%;
    background: rgba(249, 247, 234, .08);
    cursor: pointer;
    transition: background-color .2s ease, border-color .2s ease, transform .2s ease;
}
.evtd-lb-close::before,
.evtd-lb-close::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 1.5px;
    background: var(--hr-cream-500);
    border-radius: 2px;
}
.evtd-lb-close::before { transform: translate(-50%, -50%) rotate(45deg); }
.evtd-lb-close::after { transform: translate(-50%, -50%) rotate(-45deg); }
.evtd-lb-close:hover {
    background: rgba(249, 247, 234, .16);
    border-color: rgba(249, 247, 234, .34);
    transform: translateY(-2px);
}
/* Edge to edge: the media is the point, so the stage carries no padding and
   the black behind it does the letterboxing for any aspect ratio. */
.evtd-lb .modal-body {
    padding: 0;
    background: #000;
}
.evtd-lb .modal-footer {
    justify-content: flex-start;
    padding: 14px 24px;
    border-top: 1px solid rgba(249, 247, 234, .12);
}
/* Turns the lightbox from a dead end into a way through to the gathering the
   item belongs to — the same destination the card's caption links to. */
.evtd-lb-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 700;
    color: var(--hr-yellow-400);
    text-decoration: none;
}
.evtd-lb-link:hover { color: var(--hr-yellow-400); text-decoration: underline; }
.evtd-lb-link img { display: block; }
@media (max-width: 767.98px) {
    .evtd-lb .modal-dialog { width: calc(100% - 16px); }
    .evtd-lb .modal-header { padding: 16px; }
    .evtd-lb .modal-footer { padding: 12px 16px; }
    .evtd-lb-title { font-size: 17px; line-height: 24px; }
    .evtd-lb-close { width: 34px; height: 34px; }
}

/* ---------- Video stage ---------- */

/* ---------- Photo stage (single photo) ----------
   The dialog shows one photo - the one that was clicked. The Swiper that used
   to live here, with its arrows and pagination, is gone: the moments gallery
   behind the dialog already scrolls, so paging the same photos again inside it
   duplicated navigation the visitor had just used. Everything that styled that
   chrome (.evtd-lb-photo-swiper / -arrow / -prev / -next / -pagination and the
   -single hide rule) came out with it. */
.evtd-lb-photo-stage {
    width: 100%;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* contain, not cover: these are whole photographs, so the frame letterboxes
   them rather than cropping. */
.evtd-lb-photo-stage img {
    width: 100%;
    max-height: min(70vh, 620px);
    object-fit: contain;
}
