  h1,h2,h3,.display{ font-family:'ABCNormal',sans-serif; letter-spacing:-0.01em; color:var(--ink); }
  .mono{ font-family:'ABCNormal',sans-serif; letter-spacing:0.04em; }
  .pane{ border:1px solid var(--line); position:relative; }
  .pane::before,.pane::after{ content:""; position:absolute; width:9px;height:9px; border:1px solid var(--green); }
  .pane::before{top:-1px;left:-1px;border-right:none;border-bottom:none;}
  .pane::after{bottom:-1px;right:-1px;border-left:none;border-top:none;}
  nav a.active{color:var(--ink);}
  nav a.active::after,nav a:hover::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:2px; background:var(--green); }
  /* ── HERO: FULL-BLEED CINEMATIC ── */
  .hero{ padding:0; overflow:hidden; position:relative; margin-top:0; }
  .hero-bg{
    position:relative; width:100%;
    min-height:86vh; display:flex; flex-direction:column; justify-content:flex-end;
    overflow:hidden;
  }
  @media (max-width:640px){ .hero-bg{min-height:100svh;} }
  .hero-bg-img{
    position:absolute; inset:0;
    background:var(--ink);
  }
    /* Crossfade slideshow.
       How long a round takes, and when each picture takes its turn, are set on
       the slides themselves: the page knows how many there are and this file
       does not. Two delays were once written in here, so a third picture had no
       turn of its own and faded in on top of the first — which looked as though
       it was being ignored. */
    .hero-slide{
      position:absolute; inset:0;
      opacity:0;
      animation-name:heroFade;
      animation-iteration-count:infinite;
      animation-fill-mode:both;
    }
  .hero-slide img{
    width:100%; height:100%; object-fit:cover; display:block;
    object-position:center 30%;
  }
  /* First slide crops toward the crowd so less ceiling/roof shows */
  .hero-slide:nth-child(1) img{ object-position:center 82%; transform:scale(1.18); transform-origin:center bottom; }
  /* Banner video — same box as a slide, cropped the same way. .hero-still is the
     poster standing in for it on phones and under reduced motion. */
  .hero-video,
  .hero-still{
    position:absolute; inset:0;
    width:100%; height:100%;
    object-fit:cover; object-position:center 30%;
    display:block;
  }
  /* Hidden until something asks for it. It shares the video's box, so left
     visible it would simply cover the video — which is what happened when
     "play the video on phones" was chosen and the narrow-only class went away. */
  .hero-still{
    background-size:cover; background-position:center 30%; background-repeat:no-repeat;
    display:none;
  }
  @media (max-width:640px){
    .hero-video--wide-only{ display:none; }
    .hero-still--narrow-only{ display:block; }
  }
  /* Someone who has asked their system for less motion gets the still image. */
  @media (prefers-reduced-motion: reduce){
    .hero-video{ display:none; }
    .hero-still{ display:block; }
  }
  .hero-bg-overlay{
    position:absolute; inset:0;
    background:linear-gradient(
      to bottom,
      rgba(var(--ink-rgb,19,32,27),0.30) 0%,
      rgba(var(--ink-rgb,19,32,27),0.60) 35%,
      rgba(var(--ink-rgb,19,32,27),0.88) 70%,
      rgba(var(--ink-rgb,19,32,27),0.97) 100%
    );
  }
  .hero-content{
    position:relative; z-index:1;
    padding:0 48px 0;
    max-width:1920px; margin:0 auto; width:100%;
  }
  @media (max-width:640px){ .hero-content{padding:0 16px 0;} }
  .hero-eyebrow{
    font-family:'ABCNormal',sans-serif; font-size:11px; letter-spacing:0.1em;
      text-transform:uppercase; color:var(--green-pale); display:flex; align-items:center; gap:10px;
    margin-bottom:24px;
    text-shadow:0 1px 8px rgba(0,0,0,0.6);
  }
  .hero h1{
    font-size:clamp(38px,5.5vw,76px); line-height:1.0; font-weight:700;
    color:var(--paper); margin:0 0 24px; letter-spacing:-0.02em;
    max-width:900px;
    text-shadow:0 2px 16px rgba(0,0,0,0.4);
  }
  .hero p.lede{
    font-size:clamp(14px,1.4vw,17px); color:rgba(250,248,242,0.72);
    max-width:580px; line-height:1.7; margin-bottom:36px;
  }
  .hero-actions{ display:flex; gap:14px; flex-wrap:wrap; margin-bottom:0; }
  .btn-line{ border-color:rgba(250,248,242,0.4); color:var(--paper); }
  .btn-line:hover{ border-color:var(--paper); color:var(--paper); }
  /* Bottom info bar */
  .hero-bar{
    position:relative; z-index:1;
    display:grid; grid-template-columns:1fr 1fr 1fr;
    border-top:1px solid rgba(250,248,242,0.18);
    margin-top:40px;
    max-width:1920px; width:100%; margin-left:auto; margin-right:auto;
    padding:0 48px;
  }
  @media (max-width:640px){ .hero-bar{grid-template-columns:1fr 1fr; padding:0 16px;} }
  .hero-bar-cell{
    padding:20px 28px; border-right:1px solid rgba(250,248,242,0.18);
    display:flex; flex-direction:column; gap:4px;
  }
  .hero-bar-cell:last-child{ border-right:none; }
  @media (max-width:640px){ .hero-bar-cell:last-child{ display:none; } }
  .hero-bar-cell .hb-label{
    font-family:'ABCNormal',sans-serif; font-size:10px;
    letter-spacing:0.08em; text-transform:uppercase; color:rgba(250,248,242,0.45);
  }
  /* Set to the live site. The date, the venue and the opening time are the three
     facts the banner exists to state, and at 14px they were smaller than the
     lede above them. */
  .hero-bar-cell .hb-val{
    font-size:19px; font-weight:700; color:var(--paper); letter-spacing:-0.01em;
  }
  .hero-bar-cell .hb-sub{
    font-size:12.5px; color:rgba(250,248,242,0.6); margin-top:3px;
  }
  /* Numbers bar */
  /* As many columns as there are figures.
     ---------------------------------------------------------------------------
     Fixed at four, which suited the doors show's four. The aluminium show has
     three, so the row ended a quarter short of the right edge and the whole band
     read as misaligned. The page counts them and says so in --num-cols. */
  .hero-nums{
    position:relative; z-index:1;
    display:grid; grid-template-columns:repeat(var(--num-cols,4),1fr);
    border-top:1px solid rgba(250,248,242,0.10);
    max-width:1920px; width:100%; margin-left:auto; margin-right:auto;
    padding:0 48px;
  }
  @media (max-width:640px){ .hero-nums{grid-template-columns:repeat(2,1fr); padding:0 16px;} }
  .hero-num-cell{
    padding:22px 28px; border-right:1px solid rgba(250,248,242,0.10);
    display:flex; align-items:baseline; gap:12px;
  }
  .hero-num-cell:last-child{ border-right:none; }
  .hero-num-cell .hn-fig{
    font-family:'ABCNormal',sans-serif; font-size:clamp(28px,3vw,42px);
    font-weight:700; color:var(--paper); line-height:1; letter-spacing:-0.02em;
  }
  .hero-num-cell .hn-label{
    font-size:12px; color:rgba(250,248,242,0.55); line-height:1.3;
  }
  .numbers-grid{ display:grid; grid-template-columns:repeat(4,1fr); border-left:1px solid var(--line); border-bottom:1px solid var(--line); }
  @media (max-width:760px){ .numbers-grid{grid-template-columns:repeat(2,1fr);} }
  .num-cell{ border-right:1px solid var(--line); padding:38px 28px; }
  .num-cell .figure{ font-family:'ABCNormal',sans-serif; font-size:48px; font-weight:700; color:var(--moss); line-height:1; }
  .num-cell .label{ margin-top:10px; font-size:13px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:0.06em; }
  section{padding:64px 0;}
  /* ── ABOUT THE EVENT ── */
  .about-section{ border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
  .about-headline{
    padding:40px 0 48px;
    border-bottom:1px solid var(--line);
  }
  .about-headline .eyebrow{ margin-bottom:28px; display:block; }
  .about-headline h2{
    font-size:clamp(36px,5.5vw,80px); font-weight:700;
    line-height:0.95; letter-spacing:-0.025em;
    max-width:1200px;
  }
  /* Editorial grid. The column widths are set on the element by the template —
     the text column plus one per panel the office has made — so nothing here
     assumes how many there are. */
  .about-body{
    display:grid; grid-template-columns:minmax(0,2fr) 1fr 1fr;
    border-bottom:1px solid var(--line);
  }
  @media(max-width:900px){ .about-body{grid-template-columns:1fr 1fr;} }
  @media(max-width:560px){ .about-body{grid-template-columns:1fr;} }
  .ab-col{
    padding:40px 40px 40px 0;
    border-right:1px solid var(--line);
  }
  .ab-col:last-child{ border-right:none; padding-right:0; }
  @media(max-width:900px){
    /* Two across is all there is room for, and the words take the full width
       above them — a panel stranded under the text at half width reads as a
       mistake rather than a column. */
    .about-body{ grid-template-columns:1fr 1fr !important; }
    .about-body > .ab-col:first-child{ grid-column:1 / -1; border-right:none; padding-right:0; }
  }
  @media(max-width:560px){
    .ab-col{ border-right:none; border-bottom:1px solid var(--line); padding:32px 0; }
    .ab-col:last-child{ border-bottom:none; }
  }
  .ab-col .ab-label{ font-family:'ABCNormal',sans-serif; font-size:11px; letter-spacing:0.1em; text-transform:uppercase; color:var(--green-deep); display:block; margin-bottom:20px; }

  .ab-col p{ color:var(--ink-soft); font-size:15.5px; line-height:1.75; margin-bottom:14px; }
  .ab-col p:first-of-type{ font-size:17px; color:var(--ink); font-weight:500; line-height:1.6; }
  /* Stats — built on the co-located card beside it, so both middle and right
     columns keep one rhythm however many items are added to either. */
  /* Under the About text rather than in a column of their own, and side by
     side, which is what keeps the left column from running much taller than
     the panels beside it. */
  .about-stats{
    display:grid; grid-template-columns:1fr 1fr;
    /* No column gap — the padding either side of the rule does that job. A row
       gap only shows once a third figure wraps onto a line of its own. */
    gap:26px 0;
    margin-top:28px; padding-top:26px; border-top:1px solid var(--line);
  }
  .about-stat{
    display:flex; flex-direction:column; align-items:flex-start; gap:6px;
  }
  /* A rule between the figures, the way the live site sets them. The line is the
     right-hand figure's left edge rather than a gap between them, so it runs the
     full height of the taller one and the two read as a pair of columns instead
     of two loose blocks. The padding, not a grid gap, is what keeps the numbers
     off it.

     Keyed to the column, not to first/last: "By the numbers" is a list the
     office can add to, and with a third figure the last-child rule would have
     put a stray line down the left of a figure that had wrapped to its own row
     while the middle one got none at all. In a two-column grid every even child
     is in the right-hand column, whatever the count. */
  .about-stat:nth-child(odd){ padding-right:40px; }
  .about-stat:nth-child(even){ border-left:1px solid var(--line); padding-left:40px; }
  /* Stacked, nothing sits beside anything, so the rule turns: the line that
     divided two columns becomes the line that divides two rows.

     Taking the left-hand rule away without putting anything in its place
     left the figures as two loose blocks with only a gap between them,
     which is not how they read anywhere else on the page — every other
     stacked block here is closed off by a rule.

     Written as "a figure that follows a figure" rather than by column, so a
     third and fourth get one too and the first, which already has the rule
     above the whole block, does not get a second. */
  @media(max-width:560px){
    .about-stats{ grid-template-columns:1fr; gap:0; }
    .about-stat:nth-child(odd){ padding-right:0; }
    .about-stat:nth-child(even){ border-left:none; padding-left:0; }
    .about-stat + .about-stat{
      border-top:1px solid var(--line);
      margin-top:22px; padding-top:22px;
    }
  }
  .about-stat .st-num{ font-family:'ABCNormal',sans-serif; font-size:clamp(28px,3vw,42px); font-weight:700; color:var(--ink); line-height:1.05; letter-spacing:-0.02em; display:block; }
  .about-stat .st-label{ font-size:13px; color:var(--ink-soft); line-height:1.5; margin-top:2px; }
  /* ── PANELS — runs alongside, sister event, and any the office adds ──
     The logos arrive in whatever colours their owners use: one blue, one red,
     one magenta. Knocking them out to white on the deep green is the only
     treatment that makes them read as one set, and it keeps working for a
     logo nobody has seen yet. Hover brings the real colours back. */
  .ab-col--panel{
    background:var(--green-deep);
    padding:40px;
    border-right:1px solid rgba(143,205,168,0.22);
    display:flex; flex-direction:column;
  }
  .ab-col--panel:last-child{ border-right:none; }
  /* The last panel runs out to the edge of the wrap so the band finishes
     against the page rather than stopping short in the gutter. */
  @media(min-width:901px){
    .about-body > .ab-col--panel:last-child{ margin-right:-48px; padding-right:48px; }
  }
  /* White, not the pale green — on the band a topic has to read as a heading. */
  .ab-col--panel .ab-label{ color:var(--paper); }

  .ko-card{
    display:flex; flex-direction:column; align-items:flex-start;
    padding:20px 0; border-bottom:1px solid rgba(143,205,168,0.22);
  }
  .ko-card:first-of-type{ padding-top:0; }
  .ko-card:last-of-type{ border-bottom:none; }

  /* The columns all stretch to the tallest, which is the words on the left.
     Left alone the whole difference lands under the last logo as one blank
     slab. The cards share it instead, and the last one sits its content on the
     bottom edge so the panel finishes level with the column beside it — a card
     that is also the first is a lone card, and stays where it is. */
  /* .ab-col--panel .ko-card{ flex:1 1 auto; } */
  /* .ab-col--panel .ko-card:not(:first-of-type):last-of-type{ justify-content:flex-end; } */

  /* Height and width are both capped, so a wide mark scales down instead of
     overflowing and a tall one still fills the box. Sizing on height alone is
     what used to leave the widest logo the smallest thing in the row. */
  .ko-well{ height:84px; display:flex; align-items:center; margin-bottom:12px; }
  .ko-well img{
    height:84px; max-width:100%; width:auto; display:block;
    object-fit:contain; object-position:left center;
    filter:brightness(0) invert(1); opacity:0.92;
    transition:filter 0.22s ease, opacity 0.22s ease;
  }
  /* No panel behind the logo on hover — the true colours go straight onto the
     green, and a thin paper-coloured halo keeps the black parts of a mark from
     disappearing into it. */
  .ko-card:hover .ko-well img,
  .ko-card:focus-visible .ko-well img{
    filter:drop-shadow(0 0 1px rgba(250,248,242,0.95))
           drop-shadow(0 0 3px rgba(250,248,242,0.55));
    opacity:1;
  }
  .ko-desc{ font-size:13px; color:rgba(250,248,242,0.68); margin-bottom:2px; }
  .ko-card .clink{
    font-family:'ABCNormal',sans-serif; font-size:11px; letter-spacing:0.06em;
    text-transform:uppercase; margin-top:-2px;
    transition:color 0.2s;
  }
  /* The link carries no colour of its own, so on paper it takes the green-deep
     the paper rules give it. The green band has no such rule and the link would
     inherit ink — near-black on dark green — so the band names its own, the way
     the date above does. */
  .about-body--band .ko-card .clink{ color:var(--green-pale); }
  .ko-card:hover .clink{ color:var(--paper); }

  /* When and where — filled in for a sister event, left blank for a
     co-located show, so the block is simply absent on most cards. */
  /* Stretched, because the card is a flex column that otherwise shrinks each
     child to its text — which left the rule under the date the width of the
     longest line rather than the width of the column. */
  .ko-card .se-info{ display:block; align-self:stretch; margin-top:2px; }
  /* No step between the mark and the facts under it — the date carries its own
     space below the logo. Cards without a date have no .se-info and are
     untouched either way. */
  .ab-col--panel .ko-card .se-info{ margin-top:0; }
  /* Block, not inline-block: the underline has to run the full width of the
     column so it reads as the same rule that divides two logo cards, rather
     than as a line that happens to be the length of the date. */
  /* The live site's proportions. The date is a caption above the rule, not a
     figure: at 14px bold it sits at the same rank as the venue and place
     beneath it, which is what keeps the logo the largest thing on the card. */
  /* inline-block, so the rule under the date is as wide as the date rather
     than as wide as the column — 109px against the card own 349. That is
     what the live sites draw: an underline belonging to the date, not a
     divider across the panel.

     It used to be block here, with Doors & Windows overriding it below to
     get the live behaviour. Glass Technology asked for the same, which
     makes it the shared rule rather than a pair of exceptions. */
  .ko-card .se-date{
    display:inline-block; font-family:'ABCNormal',sans-serif;
    font-size:14px; font-weight:700; line-height:1.6;
    letter-spacing:0.01em;
    margin-bottom:15px; padding-bottom:40px;
    border-bottom:1px solid rgba(143,205,168,0.22);
  }
  /* The date carries no colour of its own, so on paper it takes the green-deep
     the paper rules give it. The green band has no such rule and the date
     would inherit ink — near-black on dark green — so the band names its own. */
  .about-body--band .ko-card .se-date{ color:var(--green-pale); }
  .ko-card .se-place{ display:block; font-size:13px; color:rgba(250,248,242,0.68); line-height:1.5; }
  .ko-card .se-venue{ display:block; font-size:13px; font-weight:600; line-height:1.5; color:var(--paper); margin-bottom:1px; }

  /* ── PAPER TREATMENT — the alternative, as the live site draws it ─────
     Same markup, same content. The green goes, the panels stay on the page's
     own paper with a hairline between them, and every logo keeps the colours
     its owner supplied. Chosen under Home → About the event → Panel treatment.

     Everything here undoes a green-band rule rather than adding a new idea, so
     the two stay in step: change the band and only its own rules move. */
  .about-body--paper .ab-col--panel{
    background:transparent;
    padding:40px 40px 40px 36px;
    border-right:1px solid var(--line);
  }
  .about-body--paper .ab-col--panel:last-child{ border-right:none; padding-right:0; }
  /* No bleed: without a green field to run off the page there is nothing to
     carry to the edge, and the column lines up with the text above it instead. */
  @media(min-width:901px){
    .about-body--paper > .ab-col--panel:last-child{ margin-right:0; }
  }
  .about-body--paper .ab-col--panel .ab-label{ color:var(--green-deep); }
  .about-body--paper .ko-card{ border-bottom-color:var(--line); }
  /* The mark as supplied. multiply drops the white box the flat files carry,
     the same way the sponsor band handles them. */
  .about-body--paper .ko-well img{
    filter:none; opacity:1; mix-blend-mode:multiply;
  }
  .about-body--paper .ko-card:hover .ko-well img,
  .about-body--paper .ko-card:focus-visible .ko-well img{ filter:none; }
  .about-body--paper .ko-desc{ color:var(--ink-soft); }
  .about-body--paper .ko-card .clink{ color:var(--green-deep); }
  .about-body--paper .ko-card:hover .clink{ color:var(--green); }
  .about-body--paper .ko-card .se-date{
    color:var(--green-deep); border-bottom-color:var(--line);
  }
  .about-body--paper .ko-card .se-place{ color:var(--ink-soft); }
  .about-body--paper .ko-card .se-venue{ color:var(--ink); }
  .profile-bg{ background:var(--ink); color:var(--paper); padding:64px 0 0; overflow:hidden; }
  .profile-head{
    display:flex; justify-content:space-between; align-items:flex-end;
    flex-wrap:wrap; gap:20px; padding-bottom:40px;
    border-bottom:1px solid rgba(250,248,242,0.14);
    margin-bottom:0;
  }
  .profile-head .eyebrow{ color:var(--green-pale); }
  .profile-head h2{ color:var(--paper); font-size:clamp(26px,3vw,36px); margin-top:12px; }
  .profile-band{
    display:grid;
    grid-template-columns:repeat(var(--pc-cols, 5), 1fr);
    border-top:1px solid rgba(250,248,242,0.14);
    border-left:1px solid rgba(250,248,242,0.14);
    margin:0 -48px; /* bleed to edges */
  }
  @media(max-width:900px){ .profile-band{ grid-template-columns:repeat(3,1fr); } }
  @media(max-width:520px){ .profile-band{ grid-template-columns:repeat(2,1fr); margin:0 -22px; } }
  @media(max-width:400px){ .profile-band{ margin:0 -16px; } }
  .profile-cell{
    border-right:1px solid rgba(250,248,242,0.14);
    border-bottom:1px solid rgba(250,248,242,0.14);
    padding:28px 24px 24px;
    display:flex; flex-direction:column; justify-content:space-between;
    min-height:150px; cursor:default;
    transition:background 0.2s;
  }
  .profile-cell:hover{ background:rgba(var(--green-rgb,47,122,77),0.12); }
  /* The whole tile is a link, so it has to stop looking like body copy. */
  a.profile-cell{ text-decoration:none; color:inherit; cursor:pointer; }
  a.profile-cell:focus-visible{ outline:2px solid var(--green-pale); outline-offset:-3px; }
  .profile-cell .idx{
    font-family:'ABCNormal',sans-serif; font-size:10px;
    color:rgba(var(--green-pale-rgb,143,205,168),0.6); letter-spacing:0.08em;
  }
  .profile-cell .name{
    font-size:clamp(15px,1.8vw,20px); font-weight:700; color:var(--paper);
    line-height:1.2; letter-spacing:-0.01em;
  }

  /* ── CATEGORY DRAWINGS ──────────────────────────────────────────────
     Line art, so each takes the band's colour instead of carrying its own,
     and stays sharp at any size. overflow:visible because several of the
     animations move a part of the drawing past the edge of its box. */
  .pc-icon{ display:block; width:44px; height:44px; color:var(--green-pale); }
  .pc-icon svg{ width:100%; height:100%; overflow:visible; display:block; }
  /* Number and name travel together at the foot of the tile, whether or not
     there is a drawing above them. */
  .pc-foot{ display:flex; flex-direction:column; gap:8px; }
  .pc-foot .idx{ margin:0; }
  .pc-foot .name{ margin-top:0; }

  /* fill-box, so a transform-origin of "left center" means the left edge of
     the shape itself rather than of the whole 48-unit canvas. */
  .ic-shine,.ic-door-panel,.ic-clad-bar,.ic-gear,.ic-rail-bar,.ic-handle,.ic-sheet,.ic-dot,
  .ic-roller,.ic-feed,.ic-ram,.ic-spray,.ic-crate,.ic-gleam{ transform-box:fill-box; }
  @keyframes pcSpin{ to{ transform:rotate(360deg); } }
  @keyframes pcSwing{ 0%,100%{ transform:scaleX(1); } 50%{ transform:scaleX(0.56); } }
  @keyframes pcShine{ 0%{ transform:translateX(-18px); } 55%,100%{ transform:translateX(34px); } }
  @keyframes pcSlide{ 0%{ transform:translateX(-16px); opacity:0; } 22%,78%{ transform:translateX(0); opacity:1; } 100%{ transform:translateX(-16px); opacity:0; } }
  @keyframes pcLight{ 0%,100%{ opacity:0.18; } 50%{ opacity:1; } }
  @keyframes pcDrawUp{ 0%{ transform:scaleY(0); } 32%,100%{ transform:scaleY(1); } }
  @keyframes pcHandle{ 0%,100%{ transform:rotate(0); } 42%,58%{ transform:rotate(23deg); } }
  @keyframes pcStack{ 0%{ transform:translateY(-15px); opacity:0; } 26%,100%{ transform:translateY(0); opacity:1; } }
  @keyframes pcDot{ 0%,100%{ transform:scale(0.55); opacity:0.3; } 50%{ transform:scale(1); opacity:1; } }
  /* The ram of an extrusion press, pushing and drawing back; and the fan of a
     spray booth, falling and fading. Both taken from the Aluminium Extrusions
     site, which draws its own six categories rather than borrowing the nine
     from Doors & Windows. The crate above the conveyor reuses pcStack, which
     is already here for the sheets of raw material. */
  @keyframes pcPress{ 0%,100%{ transform:translateX(0); } 50%{ transform:translateX(9px); } }
  @keyframes pcSpray{ 0%{ transform:translateY(-4px); opacity:0; } 40%{ opacity:1; } 100%{ transform:translateY(4px); opacity:0; } }
  /* A short travel that fades at both ends, for a mark drawn on the face of a
     profile with nothing clipping it. pcShine above is the window's streak: it
     crosses fifty units because a clip path holds it inside the frame, and on
     an unclipped mark it would simply fly off the drawing. */
  @keyframes pcGleam{ 0%{ transform:translateX(-4px); opacity:0; } 45%{ opacity:1; } 100%{ transform:translateX(20px); opacity:0; } }
  .ic-shine{ animation:pcShine 2.8s ease-in-out infinite; }
  .ic-door-panel{ transform-origin:left center; animation:pcSwing 3.2s ease-in-out infinite; }
  .ic-clad-bar{ transform-origin:left center; animation:pcSlide 3s ease-in-out infinite; }
  .ic-fac-win{ animation:pcLight 2.4s ease-in-out infinite; }
  .ic-gear{ transform-origin:center; animation:pcSpin 5s linear infinite; }
  .ic-rail-bar{ transform-origin:bottom; animation:pcDrawUp 3s ease-in-out infinite; }
  .ic-handle{ transform-origin:left center; animation:pcHandle 2.6s ease-in-out infinite; }
  .ic-sheet{ transform-origin:center; animation:pcStack 3s ease-in-out infinite; }
  .ic-dot{ transform-origin:center; animation:pcDot 1.7s ease-in-out infinite; }
  .ic-roller{ transform-origin:center; animation:pcSpin 2.2s linear infinite; }
  .ic-feed{ transform-origin:left center; animation:pcSlide 3s ease-in-out infinite; }
  .ic-ram{ transform-origin:left center; animation:pcPress 2.6s ease-in-out infinite; }
  .ic-spray{ animation:pcSpray 1.8s ease-in-out infinite; }
  .ic-crate{ transform-origin:center; animation:pcStack 3s ease-in-out infinite; }
  .ic-gleam{ animation:pcGleam 2.8s ease-in-out infinite; }
  /* These keep moving whatever the machine asks for.

     They used to stop under prefers-reduced-motion, along with everything
     else that moves on the page. Asked for by name: the drawings are what
     makes the band read as more than a list of words, and an office whose
     machines have Windows animation switched off never saw them move.

     What still stops for anyone who asks for less movement is the motion
     that setting is really for — the banner's video, the carousel, the
     entrance the quotes make, the photographs on hover. Those sweep across
     the screen. A gear turning inside a 44px square does not, and is the
     kind of small, contained movement a drawing is made of rather than
     something happening to the page. */
  .profile-cell.cta-cell{
    background:var(--green); border-right-color:var(--green-deep);
    cursor:pointer; justify-content:flex-end; gap:28px;
    /* Takes whatever the last row has left, so the band finishes as a filled
       rectangle rather than a row with a hole in it. Where the categories fill
       the row exactly, this is one cell and nothing is spanned. */
    grid-column:var(--pc-cta-start, auto) / -1;
  }
  /* Below the wide layout the column count is set outright, so the span has to
     go with it or the tile would reach across a row it no longer belongs to. */
  @media(max-width:900px){
    .profile-cell.cta-cell{ grid-column:auto; }
  }
  .profile-cell.cta-cell:hover{ background:var(--green-deep); }
  .profile-cell.cta-cell .cta-label{
    font-family:'ABCNormal',sans-serif; font-size:11px;
    letter-spacing:0.08em; text-transform:uppercase; color:var(--paper); opacity:0.75;
  }
  .profile-cell.cta-cell .cta-arrow{ font-size:28px; color:var(--paper); line-height:1; }
  /* ── EXHIBITOR SCROLL ── */
  .exh-scroll-section{ background:var(--concrete); padding:64px 0 72px; overflow:hidden; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
  .exh-scroll-head{
    display:flex; justify-content:space-between; align-items:flex-end;
    flex-wrap:wrap; gap:16px; padding:0 48px; margin-bottom:48px;
    max-width:1920px; margin-left:auto; margin-right:auto;
  }
  @media(max-width:640px){ .exh-scroll-head{padding:0 16px; margin-bottom:32px;} }
  .exh-scroll-head h2{ font-size:clamp(26px,3vw,36px); color:var(--ink); }
  .exh-scroll-head .exh-meta{ font-size:13.5px; color:var(--ink-soft); }
  .exh-scroll-head .btn-dir{
    font-family:'ABCNormal',sans-serif; font-size:12px; letter-spacing:0.08em;
    text-transform:uppercase; color:var(--ink); border:1px solid var(--ink);
    padding:11px 20px; white-space:nowrap; transition:border-color 0.15s, color 0.15s, background 0.15s;
  }
  .exh-scroll-head .btn-dir:hover{ background:var(--ink); color:var(--paper); }
  .marquee-wrap{ display:flex; flex-direction:column; gap:0; }
  .marquee-track{ display:flex; overflow:hidden; border-top:1px solid var(--line); }
  .marquee-track:last-child{ border-bottom:1px solid var(--line); }
  .marquee-inner{
    display:flex; flex-shrink:0; will-change:transform;
  }
  /* Separate keyframes for each direction — more reliable than animation-direction:reverse */
  @keyframes marquee-left{
    from{ transform:translateX(0); }
    to{ transform:translateX(-50%); }
  }
  @keyframes marquee-right{
    from{ transform:translateX(-50%); }
    to{ transform:translateX(0); }
  }
  .marquee-inner.go-left{
    animation:marquee-left var(--dur,120s) linear infinite;
    animation-play-state:var(--mq-play, running);
  }
  .marquee-inner.go-right{
    animation:marquee-right var(--dur,120s) linear infinite;
    animation-play-state:var(--mq-play, running);
  }
  /* Pause handled by JS mouseenter/mouseleave for reliability */
  /* Logo boxes.
     --chip-w and --chip-h come from .marquee-wrap, set from the admin. The values
     here are what the band falls back to if it is ever rendered without them. */
  .exh-logo-chip{
    flex-shrink:0;
    width:var(--chip-w,148px); height:var(--chip-h,80px);
    display:flex; align-items:center; justify-content:center;
    border-right:1px solid var(--line);
    padding:18px 24px; background:var(--concrete);
    transition:background 0.2s;
  }
  .exh-logo-chip:hover{ background:var(--concrete-deep); }
  /* Fills the padded box at whatever size it is set to, so the logo is fitted
     rather than cropped or stretched. */
  .exh-logo-chip img{
    max-width:100%; max-height:100%;
    width:auto; height:auto;
    object-fit:contain; display:block;
    mix-blend-mode:multiply;
    transition:opacity 0.2s;
  }
  .exh-logo-chip:hover img{ opacity:1; }
  .exh-logo-chip:hover img{ opacity:1; mix-blend-mode:multiply; }
  .exh-initial{
    font-family:'ABCNormal',sans-serif; font-size:28px; font-weight:700;
    color:var(--line); line-height:1;
    display:flex; align-items:center; justify-content:center;
    width:100%; height:100%;
  }
  /* ── TESTIMONIALS ADDED IN THE ADMIN ──
     Shown instead of the Elfsight widget when the quotes are kept here. */
  .quote-card{
    background:var(--paper);
    padding:32px 28px 26px;
    display:flex; flex-direction:column; justify-content:space-between; gap:26px;
    margin:0;
  }
  .quote-card blockquote{
    margin:0; font-size:16px; line-height:1.65; color:var(--ink);
  }
  /* A quote mark that reads as punctuation rather than an image */
  .quote-card blockquote::before{
    content:"\201C"; display:block;
    font-size:44px; line-height:0.7; color:var(--green-pale);
    margin-bottom:12px;
  }
  .quote-card figcaption{
    display:flex; align-items:center; gap:14px;
    padding-top:20px; border-top:1px solid var(--line);
  }
  .quote-card figcaption img{
    width:52px; height:34px; object-fit:contain; flex-shrink:0;
    mix-blend-mode:multiply;
  }
  .quote-card .q-name{
    display:block; font-weight:700; font-size:14px; color:var(--ink); line-height:1.3;
  }
  .quote-card .q-role{
    display:block; font-size:12px; color:var(--ink-soft); line-height:1.4; margin-top:3px;
  }

  /* ── FEATURE CARD ──
     One quote at a time. The company's mark sits on a panel that steps out past
     the left edge; the words sit beside it; the markers run down the right. The
     slides share one grid cell, so the card takes the height of its longest
     quote and they cross-fade in place rather than jumping. */
  .quote-feature{
    position:relative;
    background:var(--paper); border:1px solid var(--line);
    margin-left:52px;                       /* room for the panel to step out */
    padding:38px 78px 38px 38px;
  }
  .qf-track{ display:grid; }
  .qf-slide{
    grid-area:1 / 1;
    display:flex; align-items:center; gap:42px;
    opacity:0; visibility:hidden;
    transition:opacity .45s ease, visibility .45s;
  }
  .qf-slide.is-active{ opacity:1; visibility:visible; }

  .qf-art{
    flex:0 0 190px; height:190px;
    margin-left:-90px;                      /* the step out */
    background:var(--green-deep);
    padding:18px;
  }
  .qf-plate{
    width:100%; height:100%;
    background:var(--paper);
    display:flex; align-items:center; justify-content:center;
    padding:16px;
  }
  .qf-plate img{ max-width:100%; max-height:100%; object-fit:contain; display:block; mix-blend-mode:multiply; }
  .qf-initial{ font-size:44px; font-weight:700; color:var(--line); line-height:1; }

  .qf-body{ min-width:0; }
  .qf-company{
    display:block; font-size:12px; letter-spacing:.12em; text-transform:uppercase;
    color:var(--green-deep); margin-bottom:14px;
  }
  .qf-quote{ margin:0 0 22px; font-size:18px; line-height:1.6; color:var(--ink); }
  .qf-who{ font-weight:700; font-size:15px; color:var(--ink); }
  .qf-role{ font-size:12.5px; color:var(--ink-soft); margin-top:3px; }

  /* The words arrive after the card has settled, one line behind the next —
     the movement the design is really made of. */
  .qf-body > *{ opacity:0; transform:translateY(22px); transition:opacity .45s ease, transform .45s ease; }
  .qf-slide.is-active .qf-body > *{ opacity:1; transform:none; }
  .qf-slide.is-active .qf-body > *:nth-child(1){ transition-delay:.30s; }
  .qf-slide.is-active .qf-body > *:nth-child(2){ transition-delay:.40s; }
  .qf-slide.is-active .qf-body > *:nth-child(3){ transition-delay:.50s; }
  .qf-slide.is-active .qf-body > *:nth-child(4){ transition-delay:.60s; }

  /* Markers down the right; the one in view stretches rather than changing size,
     so the column keeps its rhythm. Square, like every other edge on the site. */
  .qf-dots{
    position:absolute; right:34px; top:50%; transform:translateY(-50%);
    display:flex; flex-direction:column; gap:9px; z-index:2;
  }
  .qf-dots button{
    width:8px; height:8px; padding:0; border:0; cursor:pointer;
    background:var(--line);
    transition:background .3s ease, height .3s ease;
  }
  .qf-dots button[aria-current="true"]{ background:var(--green); height:28px; }
  .qf-dots button:focus-visible{ outline:2px solid var(--green); outline-offset:3px; }

  @media (max-width:860px){
    .quote-feature{ margin-left:0; padding:28px 24px 56px; }
    .qf-slide{ flex-direction:column; align-items:flex-start; gap:26px; }
    .qf-art{ margin-left:0; margin-top:-56px; flex:0 0 auto; width:150px; height:150px; }
    .qf-quote{ font-size:16px; }
    .qf-dots{
      right:auto; left:50%; top:auto; bottom:22px;
      transform:translateX(-50%); flex-direction:row;
    }
    .qf-dots button[aria-current="true"]{ height:8px; width:28px; }
  }

  /* One at a time, full width — for two or three long quotes */
  .quote-list{ display:flex; flex-direction:column; gap:20px; }
  .quote-list .quote-card blockquote{ font-size:19px; line-height:1.6; }
  .quote-list .quote-card{ padding:38px 34px 30px; }

  /* The rows come down from the top of the section and settle into a list, each a
     beat behind the one above it.

     --from is how far a row has to travel, set by script from its own distance
     below the first line: the lower it sits the further it falls, so the list
     reads as being built downwards whatever length the quotes are. */
  .js .quote-list[data-reveal] .quote-card{
    opacity:0; transform:translateY(var(--from,-40px));
  }
  .js .quote-list[data-reveal].is-in .quote-card{
    animation:quote-fall .78s cubic-bezier(.16,.8,.28,1) forwards;
    animation-delay:calc(var(--i,0) * 150ms);
  }
  @keyframes quote-fall{
    /* Solid well before it lands, so the row is readable on the way down rather
       than fading in at the last moment. */
    60%{ opacity:1; }
    to{ opacity:1; transform:none; }
  }

  /* Side by side, dragged or scrolled. Snap points so a card never stops
     half-shown; the one nearest the middle stands forward, which says the row
     moves without needing a scrollbar to say it. */
  .quote-rail{
    display:flex; gap:24px;
    overflow-x:auto; scroll-snap-type:x mandatory;
    padding-bottom:14px;
  }
  .quote-rail .quote-card{ flex:0 0 min(360px, 82vw); scroll-snap-align:center; }
  /* Half a view's worth of room at each end so the first and last card can reach
     the middle as well — otherwise the bracket could never sit centrally on them.
     max() keeps it at nothing on a narrow screen, where the card fills the view. */
  .quote-rail::before,
  .quote-rail::after{
    content:""; flex:0 0 max(0px, calc(50% - min(180px, 41vw)));
  }

  /* The bracket that rides to the card in the middle.
     Outside the scrolling row, so it glides between cards rather than being
     carried along by them. Same corner marks every card already has, grown. */
  .quote-rail-wrap{ position:relative; }
  .rail-bracket{
    position:absolute; left:0; top:0; pointer-events:none; z-index:3;
    opacity:0;
    transition:transform .42s cubic-bezier(.22,.75,.28,1), opacity .3s ease;
  }
  .rail-bracket.is-on{ opacity:1; }
  .rail-bracket span{
    position:absolute; width:26px; height:26px; border:2px solid var(--green);
  }
  .rail-bracket span:nth-child(1){ top:-5px;    left:-5px;  border-right:0; border-bottom:0; }
  .rail-bracket span:nth-child(2){ top:-5px;    right:-5px; border-left:0;  border-bottom:0; }
  .rail-bracket span:nth-child(3){ bottom:-5px; left:-5px;  border-right:0; border-top:0; }
  .rail-bracket span:nth-child(4){ bottom:-5px; right:-5px; border-left:0;  border-top:0; }
  /* Arriving, the arms reach out and settle — the lock on */
  .rail-bracket.is-lock span{ animation:bracket-lock .34s cubic-bezier(.3,1.4,.5,1); }
  @keyframes bracket-lock{
    from{ width:44px; height:44px; }
    to{ width:26px; height:26px; }
  }

  /* ── CAROUSEL ──
     One item held in the middle with its neighbours showing at the edges. Built
     on native scrolling with snap points, so a finger swipe and a trackpad work
     without any code; the arrows, dots and turning are script on top of that. */
  /* One at a time, filling the width. The neighbours are not shown at all —
     a peeking edge pulls the eye away from the quote being read. */
  .carousel{ position:relative; --slide:100%; }
  .carousel-track{
    display:flex; gap:0;
    overflow-x:auto; scroll-snap-type:x mandatory; scroll-behavior:smooth;
    /* Hides the scrollbar without hiding the scrolling */
    scrollbar-width:none; -ms-overflow-style:none;
  }
  .carousel-track::-webkit-scrollbar{ display:none; }
  /* Empty room at each end so the first and last can reach the middle as well.
     Spacers rather than padding on the track: a percentage padding would change
     the box the slide widths are measured against, and nothing would line up. */
  .carousel-track::before,
  .carousel-track::after{
    content:""; flex:0 0 calc((100% - var(--slide)) / 2);
  }
  .carousel-slide{
    flex:0 0 var(--slide); scroll-snap-align:center;
    padding:0 56px; display:flex;
  }
  .carousel-slide > *{ width:100%; }

  /* Plain text in the middle, no card — the box would fight the peeking edges */
  .carousel .quote-card{
    background:transparent; border:0; padding:8px 0 0;
    text-align:center; align-items:center; gap:20px;
    transition:opacity 0.3s ease;
  }
  .carousel .quote-card.pane::before,
  .carousel .quote-card.pane::after{ display:none; }
  .carousel .quote-card blockquote::before{ display:none; }
  .carousel .quote-card blockquote{ font-size:18px; line-height:1.55; }
  .carousel .quote-card figcaption{
    flex-direction:column; gap:8px; border-top:0; padding-top:0;
  }
  /* Name and role first, the logo beneath them */
  .carousel .quote-card figcaption img{ order:2; width:auto; height:26px; }
  .carousel .quote-card .q-role{ color:rgba(var(--ink-rgb,19,32,27),0.55); }

  .carousel-arrow{
    position:absolute; top:38%; transform:translateY(-50%);
    width:40px; height:40px; border:1px solid var(--line);
    background:var(--paper); color:var(--ink);
    font-size:22px; line-height:1; cursor:pointer; border-radius:50%;
    display:flex; align-items:center; justify-content:center;
    transition:background 0.2s, border-color 0.2s;
    z-index:2;
  }
  .carousel-arrow:hover{ background:var(--green); border-color:var(--green); color:var(--paper); }
  .carousel-arrow:focus-visible{ outline:2px solid var(--green); outline-offset:2px; }
  .carousel-prev{ left:0; }
  .carousel-next{ right:0; }

  .carousel-dots{
    display:flex; justify-content:center; gap:8px; margin-top:22px;
  }
  .carousel-dots button{
    width:7px; height:7px; padding:0; border:0; border-radius:50%;
    background:var(--line); cursor:pointer;
    transition:background 0.2s, transform 0.2s;
  }
  .carousel-dots button[aria-current="true"]{ background:var(--green); transform:scale(1.35); }
  .carousel-dots button:focus-visible{ outline:2px solid var(--green); outline-offset:3px; }

  .carousel--photos .photo-cell img{ aspect-ratio:16/10; }

  @media (max-width:640px){
    .carousel-slide{ padding:0 8px; }
    .carousel-arrow{ display:none; }
    .carousel .quote-card blockquote{ font-size:16px; }
  }

  /* ── PHOTO GALLERY ADDED IN THE ADMIN ── */

  /* Measured off the Elfsight gallery this replaces, so the two look the same
     whichever is switched on: 13px plain labels in a 2px-cornered chip, the
     chosen one on a 5% ink wash rather than a colour. */
  .gallery-years{
    display:flex; justify-content:center; flex-wrap:wrap; gap:4px;
    margin-bottom:24px;
  }
  .gallery-years button{
    font-family:'ABCNormal',sans-serif; font-size:13px; font-weight:400;
    padding:5px 11px; cursor:pointer;
    background:transparent; color:rgba(var(--ink-rgb,19,32,27),0.5);
    border:0; border-radius:2px;
    transition:background 0.2s, color 0.2s;
  }
  .gallery-years button:hover{ color:var(--ink); }
  .gallery-years button[aria-pressed="true"]{ background:rgba(var(--ink-rgb,19,32,27),0.05); color:var(--ink); }
  .gallery-years button:focus-visible{ outline:2px solid var(--green); outline-offset:2px; }

  /* Held back until Load more is pressed, or until a year is chosen that brings
     the count under the batch. */
  .js .photo-cell[hidden]{ display:none; }

  .gallery-more{ display:flex; justify-content:center; margin-top:26px; }
  .gallery-more button{
    font-family:'ABCNormal',sans-serif; font-size:15px; font-weight:400;
    text-transform:uppercase; padding:16px 60px; cursor:pointer;
    background:transparent; color:var(--green-deep);
    border:2px solid var(--green-deep); border-radius:0;
    transition:background 0.2s, color 0.2s;
  }
  .gallery-more button:hover{ background:var(--green-deep); color:var(--paper); }
  .gallery-more button:focus-visible{ outline:2px solid var(--green); outline-offset:3px; }

  /* Masonry, as the widget lays it out: each photo keeps its own proportions and
     the column takes whatever height that comes to. Nothing is cropped, which is
     the point — a stand photo and a wide hall shot both arrive whole. */
  .photo-grid{
    columns:4; column-gap:10px;
  }
  .photo-rail{
    display:flex; gap:16px;
    overflow-x:auto; scroll-snap-type:x mandatory;
    padding-bottom:14px;
  }
  .photo-rail .photo-cell{ flex:0 0 min(320px, 76vw); scroll-snap-align:start; }

  /* Jumping straight there beats gliding for anyone who asked for less movement.
     Everything still works and everything is still visible — what goes is the
     travelling: no rising, no rule drawing itself, no gliding between slides. */
  @media (prefers-reduced-motion: reduce){
    .carousel-track{ scroll-behavior:auto; }
    .carousel .quote-card{ transition:none; }
    /* The .is-in selectors are matched here too: they carry an extra class, so a
       plainer selector would lose to them and the entrance would still run. */
    .qf-slide,
    .qf-body > *,
    .qf-slide.is-active .qf-body > *{ transition:none; }
    .js .quote-list[data-reveal] .quote-card,
    .js .quote-list[data-reveal].is-in .quote-card{
      opacity:1; transform:none; animation:none;
    }
    /* The bracket still marks the card — it simply stops gliding and flicking. */
    .rail-bracket{ transition:opacity .3s ease; }
    .rail-bracket.is-lock span{ animation:none; }
  }
  /* Plain photos, as the widget shows them — no frame, no tinted bed. In the
     masonry columns each keeps its own height; in the rail and carousel, where the
     cells must match, they are cropped to a common shape instead. */
  .photo-cell{
    margin:0 0 10px; overflow:hidden;
    break-inside:avoid;
  }
  .photo-cell img{
    display:block; width:100%; height:auto;
    /* "auto" first: the photo's own proportions win as soon as they are known, and
       3:2 holds the space until then. Without it a photo yet to arrive is zero
       tall, the columns are measured wrong, and the page jumps as each one lands. */
    aspect-ratio:auto 3 / 2;
    transition:opacity 0.3s ease;
  }
  .photo-cell:hover img{ opacity:0.86; }
  .photo-cell figcaption{
    padding:8px 0 2px; font-size:12px; color:var(--ink-soft);
  }
  /* A row cannot have ragged heights, so there the photos are cropped to shape */
  .photo-rail .photo-cell img,
  .carousel--photos .photo-cell img{ aspect-ratio:16/10; object-fit:cover; }
  .photo-rail .photo-cell,
  .carousel--photos .photo-cell{ margin-bottom:0; background:var(--concrete-deep); }

  @media (prefers-reduced-motion: reduce){
    .photo-cell img{ transition:none; }
  }
  @media (max-width:1024px){
    .photo-grid{ columns:3; }
  }
  @media (max-width:640px){
    .photo-grid{ columns:2; column-gap:8px; }
    .quote-card{ padding:26px 22px 22px; }
  }

  /* ── SPONSORS: HORIZONTAL TIER ROWS ── */
  .sponsor-tier{
    display:grid; grid-template-columns:180px 1fr;
    border-top:1px solid var(--line); padding:28px 0;
    gap:0; align-items:start;
  }
  .sponsor-tier:last-child{ border-bottom:1px solid var(--line); }
  .sponsor-tier.plat-tier{ border-top:2px solid var(--green); background:var(--concrete); padding:32px 0; }
  @media (max-width:760px){ .sponsor-tier{grid-template-columns:1fr; gap:16px;} }
  .tier-col{
    padding:4px 32px 0 0; border-right:1px solid var(--line);
  }
  @media (max-width:760px){ .tier-col{border-right:none; padding-right:0;} }
  .tier-label{
    font-family:'ABCNormal',sans-serif; font-size:11px; letter-spacing:0.1em;
    text-transform:uppercase; color:var(--green-deep); display:block;
  }
  .sponsor-tier img{ max-height:60px; max-width:200px; width:auto; height:auto; object-fit:contain; mix-blend-mode:multiply; display:block; }
  .logos-col{ padding-left:32px; display:flex; align-items:center; }
  @media (max-width:760px){ .sponsor-tier img{ max-height:60px; max-width:200px; width:auto; height:auto; object-fit:contain; mix-blend-mode:multiply; display:block; }
  .logos-col{padding-left:0;} }
  /* Platinum logo — large, clickable, greyscale → colour on hover */
  .plat-logo-link{ display:inline-flex; align-items:center; }
  .plat-logo-link:hover img{ opacity:1; }
  /* Logo chips — wrapping flex with collapsed borders */
  .logo-flow{ display:flex; flex-wrap:wrap; }
  .logo-chip{
    padding:16px 20px; display:flex; align-items:center; justify-content:center;
    border:1px solid var(--line); margin:-1px 0 0 -1px;
    position:relative;
    transition:background 0.15s;
  }
  /* No z-index here. It would make the hovered tile a stacking context of its
     own, and multiply would then blend the logo against that group instead of
     against the paper behind the band — which is exactly how a white box
     appears behind a logo the moment it is pointed at. The tooltip does its own
     stacking below. */
  .logo-chip:hover{ background:transparent; }
  .logo-chip img{
    max-height:28px; max-width:100px; width:auto; object-fit:contain;
    opacity:0.85;
    transition:opacity 0.15s;
  }
  .logo-chip:hover img{ opacity:1; }
  /* No name on hover. The tooltip that used to sit above each tile is gone:
     the marks are the point of the band, and a black label popping up over the
     one next to it was reading as an error rather than a help. The name is
     still on the image as its alt text, which is what a screen reader uses. */
  .cta-band{ background:var(--green); color:var(--paper); padding:72px 0; }
  .cta-inner{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:28px; }
  .cta-inner h2{color:var(--paper); font-size:clamp(26px,3.4vw,40px); max-width:560px; line-height:1.08;}
  .cta-inner .btn{border-color:var(--paper);}
  .cta-inner .btn-fill{background:var(--ink); border-color:var(--ink); color:var(--paper);}
  .cta-inner .btn-line{color:var(--paper);}
  .cta-inner .btn-line:hover{background:rgba(0,0,0,0.12); color:var(--paper); border-color:var(--paper);}
  .foot-grid a:hover{color:var(--paper);}
  .foot-social a:hover{ color:var(--paper); border-color:var(--green-pale); }
  .video-section{ border-bottom:1px solid var(--line); }
  /* Padding-top rather than aspect-ratio: the frame is positioned inside the
     box, which is what keeps a 16:9 video from letterboxing itself. */
  .ep-video{
    position:relative; width:100%; padding-top:56.25%; border:1px solid var(--line);
    background:var(--ink); overflow:hidden;
  }
  .ep-video iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; display:block; }
  /* HAMBURGER */
  /* MOBILE NAV OVERLAY */
  /* A second header button stacks under the first rather than repeating the
     gap that separates them from the menu. */
  .mobile-nav .mob-cal + .mob-cal{ margin-top:10px; }
  /* ═══ MOBILE COMPREHENSIVE ═══ */
  /* Hide actions buttons on very small screens, keep just hamburger */

  /* ══════════════════════════════════
     MOBILE — max-width: 980px (tablet)
     ══════════════════════════════════ */
  /* ══════════════════════════════════
     MOBILE — max-width: 768px
     ══════════════════════════════════ */
  @media (max-width:768px){
    .wrap,.header-wrap{ padding:0 22px; }
  }
  /* ══════════════════════════════════
     MOBILE — max-width: 640px
     ══════════════════════════════════ */
  @media (max-width:640px){
    /* Global */
    .wrap,.header-wrap{ padding:0 16px !important; }
    section{ padding:40px 0 !important; } .hero{ padding:0 !important; } .page-hero{ padding:0 !important; }
    h2{ font-size:clamp(22px,6vw,32px) !important; }
    /* Header */
    /* Hero */
    .hero-bg{ min-height:100svh; }
    .hero-content{ padding:0 16px 0 !important; }
    .page-hero h1{ font-size:clamp(30px,8vw,48px) !important; }
    .ph-content{ padding:0 16px 32px !important; }
    .hero-bar{
      grid-template-columns:1fr 1fr !important;
      padding:0 16px !important;
    }
    .hero-bar-cell:last-child{ display:none; }
    .hero-nums{
      grid-template-columns:repeat(2,1fr) !important;
      padding:0 16px !important;
    }
    /* About section */
    .about-headline{ padding:28px 0 32px !important; }
    .about-body{ grid-template-columns:1fr !important; }
    .ab-col{
      padding:28px 0 !important;
      border-right:none !important;
      border-bottom:1px solid var(--line);
    }
    .ab-col:last-child{ border-bottom:none; }
    /* Stacked, the band is the full width of the screen. */
    .ab-col--panel{
      padding:28px 16px !important; margin:0 -16px !important;
      border-right:none !important; border-bottom:none !important;
    }
    /* A panel holding more than one show puts them side by side rather than
       one above the other. They are a pair of sister shows read at a glance,
       not a list to be gone through, and stacked they pushed everything below
       — the sister event, its date, its venue — most of a screen further down.

       The rule under each card goes with it: side by side it drew a line
       under the left logo and none under the right. */
    .ab-col--panel:has(.ko-card + .ko-card){
      display:grid !important;
      grid-template-columns:1fr 1fr;
      column-gap:18px;
    }
    .ab-col--panel:has(.ko-card + .ko-card) .ab-label{ grid-column:1 / -1; }
    .ab-col--panel:has(.ko-card + .ko-card) .ko-card{
      padding-top:0 !important; border-bottom:none !important;
    }
    /* A rule between one panel and the next, the way every other stacked
       block on this page is closed off. The column of words above them has
       one; without this the two panels ran together and "Sister event" read
       as part of "Runs alongside".

       Drawn as an inset line rather than a border, because the panels bleed
       to both edges of the screen — a border on the box itself would run
       edge to edge while every other rule here stops in the gutter. */
    .ab-col--panel + .ab-col--panel{ position:relative; }
    .ab-col--panel + .ab-col--panel::before{
      content:""; position:absolute; top:0; left:16px; right:16px;
      border-top:1px solid var(--line);
    }
    /* Exhibitor profile */
    .profile-band{ grid-template-columns:repeat(2,1fr) !important; margin:0 -16px !important; }
    /* Exhibitor scroll */
    .exh-scroll-section{ padding:40px 0 !important; } .hero{ padding:0 !important; } .page-hero{ padding:0 !important; }
    .exh-scroll-head{ padding:0 16px !important; margin-bottom:24px !important; }
    /* Whatever is set, a box never gets wide enough on a phone to leave one logo
       filling the screen. Anything smaller than the cap is left alone. */
    .exh-logo-chip{
      width:min(var(--chip-w,148px),140px) !important;
      height:min(var(--chip-h,80px),70px) !important;
      padding:12px 16px !important;
    }
    /* Numbered rows (downloads, stand, venue transport) */
    .dl-row,.transport-row,.stand-option{
      grid-template-columns:1fr !important;
    }
    .dl-num,.t-num{ display:none !important; }
    .dl-body,.t-body,.stand-body{ padding:28px 0 !important; border-right:none !important; }
    .dl-action{ padding:0 0 28px !important; justify-content:flex-start !important; }
    .t-time{
      padding:0 0 28px !important;
      background:none !important;
      flex-direction:row !important;
      align-items:baseline !important;
      gap:8px;
    }
    .stand-price-col{
      padding:0 0 28px !important;
      background:none !important;
      border-top:1px solid var(--line);
    }
    /* Venue intro */
    .venue-intro{ grid-template-columns:1fr !important; }
    .venue-photo{ min-height:240px !important; }
    .venue-copy{ padding:32px 0 !important; border-left:none !important; border-top:1px solid var(--line); }
    .venue-facts{ grid-template-columns:1fr 1fr !important; }
    /* Exhibitor individual page */
    .exh-wrap{ grid-template-columns:1fr !important; }
    .exh-main{ padding:32px 0 !important; border-right:none !important; border-bottom:1px solid var(--line); }
    .exh-sidebar{ padding:32px 0 !important; }
    .exh-logo-frame{ max-width:100% !important; }
    /* Contact */
    .contact-list{ grid-template-columns:1fr !important; }
    .contact-row:first-child{ border-right:none !important; border-bottom:1px solid var(--line); }
    .c-body{ padding:32px 0 !important; }
    .form-row{ grid-template-columns:1fr !important; }
    .offices-grid{ grid-template-columns:1fr !important; }
    /* Sponsors */
    .sponsor-tier{ grid-template-columns:1fr !important; gap:16px !important; }
    .tier-col{ border-right:none !important; padding-right:0 !important; }
    .sponsor-tier img{ max-height:60px; max-width:200px; width:auto; height:auto; object-fit:contain; mix-blend-mode:multiply; display:block; }
  .logos-col{ padding-left:0 !important; }
    /* About organiser */
    .org-grid{ grid-template-columns:1fr !important; gap:24px !important; }
    /* CTA band */
    .cta-band{ padding:40px 0 !important; }
    .cta-inner{ flex-direction:column !important; gap:20px !important; align-items:flex-start !important; }
    .cta-inner .btn-group{ flex-direction:column !important; gap:10px !important; }
    /* Footer */
    /* Map label */
    .map-label{ flex-direction:column !important; gap:8px !important; }
    /* Colocate logos */
  }
  /* ══════════════════════════════════
     MOBILE — max-width: 480px
     ══════════════════════════════════ */
  @media (max-width:480px){
    .adv-list{ grid-template-columns:1fr !important; }
    .profile-band{ grid-template-columns:repeat(2,1fr) !important; }
  }
  /* ── FORCE LIGHT MODE — overrides iOS/Android dark mode ── */
  @media (prefers-color-scheme: dark) {
    html, body {
      background-color: #FAF8F2 !important;
      color: var(--ink,#13201B) !important;
    }
  }
  /* ── RESPONSIVE NAV ── */
  /* ── MOBILE CONTENT FIXES ── */
  @media (max-width:640px){
    /* Hero — give breathing room from sticky header */
    .hero-content{ padding-top:56px !important; }
    /* The bar's cells stop being a row here, so the two things that made
       them one stop earning their place: the padding that held them off
       the rule between them, and the rule itself.

       Stacked, that padding set the first cell's label on the page's own
       left edge and the two below it 28px in — a ragged edge down the
       side of the bar — and the right-hand rule drew a line down the
       outside of a full-width cell, separating it from nothing. What
       divides them here is the rule above each, which the stacked layout
       already adds. */
    .hero-bar-cell:nth-child(odd){ padding-left:0 !important; }
    .hero-bar-cell:nth-child(even){ border-right:none !important; }
    /* The figures below keep their two columns here, so they keep the rule
       between those columns — but the outer one had nothing to divide it
       from and drew a line down the right edge of the page, and the cell
       starting the second row was padded in where the one above it was
       not: 200+ on the page's edge, 22 twenty-eight pixels inside it.

       Odd cells open a row, so they lose the padding; even cells close one,
       so they lose the rule. */
    /* Three figures fit across a phone and four do not, so a show with three
       keeps them on one line rather than leaving the last one alone on a
       second row. :has with :last-child is "exactly three children".

       minmax(0,1fr) rather than 1fr: a plain fr will not shrink a track below
       its own content, so "Exhibiting brands" held its column open and the
       three ran 415 wide inside a 343 bar. */
    .hero-nums:has(> :nth-child(3):last-child){ grid-template-columns:repeat(3,minmax(0,1fr)) !important; }
    /* Three narrow columns have no room for 28px inside each, but the two that
       follow a rule still need to be held off it. The first opens the bar and
       sits on the page's own edge. */
    .hero-nums:has(> :nth-child(3):last-child) .hero-num-cell{
      padding-left:12px !important; padding-right:12px !important;
      /* The figure sits above its label rather than beside it. Beside it is
         the wide arrangement — "200+  Exhibiting brands" reads as one line
         when there is room for one — but in a third of a phone there is not,
         and the label ran out of its column and over the figure next to it. */
      flex-direction:column !important;
      align-items:flex-start !important;
      gap:2px !important;
    }
    .hero-nums:has(> :nth-child(3):last-child) .hero-num-cell:first-child{ padding-left:0 !important; }

    /* Which cell opens a row, and which closes one, is only a question of
       parity while the row is two wide. Three across, the cell that opens is
       simply the first and the one that closes is the last, which the rules
       outside this block already handle. */
    .hero-nums:not(:has(> :nth-child(3):last-child)) .hero-num-cell:nth-child(odd){ padding-left:0 !important; }
    .hero-nums:not(:has(> :nth-child(3):last-child)) .hero-num-cell:nth-child(even){ border-right:none !important; }
    .page-hero .ph-content{ padding-top:48px !important; }
    /* Footer — single column on small phones */
    /* Prevent any section horizontal overflow */
    section{ overflow-x:hidden; }
  }
  @media (max-width:480px){
    /* Hero heading size reduction */
    .hero h1{ font-size:clamp(30px,10vw,48px) !important; }
    .hero-bar{ grid-template-columns:1fr !important; }
    /* One column now, so the side padding and the rule down the right both
       stop meaning anything: the padding set the first cell's text on the
       page edge and the ones below it 28px in, and the rule drew a line
       down the outside of a full-width cell. The rule above each is what
       separates them here. */
    .hero-bar-cell{ padding:20px 0 !important; border-right:none !important; }
    .hero-bar-cell:nth-child(2){ border-top:1px solid rgba(250,248,242,0.18); border-right:none !important; }
    /* Shown again here, the two columns above having become one — but as the
       flex column the other two are, not as a block. As a block its label,
       time and note are inline and run together on one line: "Opening hours
       10:00 - 18:30 10:00 - 18:00 on Saturday". */
    .hero-bar-cell:last-child{ display:flex !important; border-top:1px solid rgba(250,248,242,0.18); }
  }
  .adv-item p{ font-size:15px !important; }
  /* Base = supporting partners size */
  /* Gold = 20% bigger than supporting */
  /* Platinum = 40% bigger than supporting */
  /* Media and associations = same as supporting */
  /* Sponsor logo sizes. Each band carries its own --sp-h and --sp-w, set from that
     tier's row under Website content › Home › Sponsor tiers. A limit, not a size:
     the logo is fitted inside and never stretched. min(…, 100%) keeps a generous
     width from running off a narrow screen. */
  .sponsor-tier .logo-chip img,
  .sponsor-tier.plat-tier .plat-logo-link img{
    max-height:var(--sp-h,66px) !important;
    max-width:min(var(--sp-w,200px), 100%) !important;
  }
  /* Every cell in a band the same size.
     ---------------------------------------------------------------------------
     The rule above limits the picture; on its own it leaves the cell to shrink
     around whatever it holds, so one band came out 152, 238, 159 and 171 wide —
     a row of mismatched boxes rather than a grid.

     The cell is the tier's allowance plus its own padding and border, so the
     numbers under Sponsor tiers keep meaning what they always did — the size the
     logo may reach — and nothing on the page changes size. What changes is that
     a narrow logo now sits in the same box as a wide one, centred in it.

     flex:0 0 auto stops a full row squeezing the cells; min(…,100%) keeps a
     generous allowance from running off a phone. */
  .sponsor-tier .logo-chip{
    flex:0 0 auto;
    width:calc(100% / var(--sp-n,10));
    height:calc(var(--sp-h,66px) + 34px);
    /* Room around the logo, in proportion to the cell it is in. Ten across makes
       a cell about 112px, where a flat 20px each side spent more than a third of
       it on nothing; the cap keeps a wide cell from going airy instead. */
    /* 100% here is the row, so dividing by the count gives this cell — a
       percentage in padding is measured against the container, never the
       element, which is why clamp(…9%…) read 9% of the whole row. */
    padding:16px min(calc(100% / var(--sp-n,10) * 0.09), 22px);
  }
  /* On a phone a tenth of the row is a stamp, so the count is only honoured
     where there is room for it. These are the two steps the bands already use. */
  @media (max-width:980px){
    .sponsor-tier .logo-chip{ width:calc(100% / min(var(--sp-n,10), 5)); }
  }
  @media (max-width:600px){
    .sponsor-tier .logo-chip{ width:calc(100% / min(var(--sp-n,10), 3)); }
  }
  /* The row has to be told to fill the column.
     ---------------------------------------------------------------------------
     .logo-flow sizes itself to its contents, so with fixed-width cells it settled
     at one cell wide — 241px inside a 1149px column — and the bands stacked in a
     single file. Filling the column is also what lets a band wrap into the even
     grid the cells are for.

     max-width above rather than min(…, 100%) on the width: a percentage there is
     measured against this element, whose own width was still being decided by the
     cells, and the cells came out at the narrow end of that circle. */
  .sponsor-tier .logo-flow{ width:100%; }
  .sponsor-tier.plat-tier .plat-logo-link img,
  .sponsor-tier.plat-tier .logo-chip img{ filter:none !important; opacity:1 !important; }
  /* ── A LOGO WALL, NOT A TABLE ──────────────────────────────────────
     The cells were ruled like a spreadsheet, which put a box round every
     partner's mark and made the band the loudest thing on the page. The live
     site draws no cell at all: the logos are simply spaced evenly and the tier
     rule above them is the only line. The even spacing stays — it comes from
     the cell widths, not from the borders. */
  .sponsor-tier .logo-chip{ border:none; margin:0; }
  /* Nothing to light up on hover either, now that there is no cell to light. */

  /* The gold band carries one logo, so it gets room rather than being divided
     into cells like the bands below it, and it sits hard against the left of
     the column instead of centred in a cell of its own.

     Width is the tier's own allowance plus its padding, capped at the row —
     not 'auto'. With auto the cell sized to its content while the logo inside
     was capped at 100% of that same cell, and the pair collapsed to a few
     pixels on a narrow screen. */
  .sponsor-tier.gold-tier .logo-chip{
    width:min(calc(var(--sp-w, 300px) + 44px), 100%);
    justify-content:flex-start;
    /* The cell keeps the same left padding as every other band, so the gold
       mark starts on the same line as the logos under it. Removing it here set
       this one logo ten pixels further left than the three tiers below. */
    /* Height follows the logo, not the tier's allowance.
       The bands below share a row between many logos, so every cell there is
       given the same height and the tall ones set it. This band holds one logo
       and has no row to share, so the fixed height only added empty space under
       it — the gold mark is wide and shallow, 300 by 45, and it was sitting in a
       cell 154 tall. */
    height:auto;
  }
  .sponsor-tier.gold-tier .logos-col,
  .sponsor-tier.gold-tier .logo-flow{ justify-content:flex-start; }

  /* The platinum band is the same kind of thing as the gold one above it, and
     wants the same treatment: it holds a single logo, so it gets the room its
     allowance promises rather than a tenth of a row it does not share.

     It had been taking a cell 160 wide — the column divided by the ten-per-row
     the tier is saved with — and the mark inside is held to 100% of that cell,
     so the 350 the office set could never be reached. Gold Plus was drawing
     131 by 74 where the live site draws it 267 by 150.

     Unlike the gold band, this one sits hard against the left of the column
     with no padding of its own. That is what the live site does: its platinum
     mark starts at 260, where the marks in the bands below start at 277 and
     281, each centred in a cell of its own. This band is a showcase, not a row,
     and it is not trying to line up with anything. */
  .sponsor-tier.plat-tier .logo-chip{
    width:min(var(--sp-w, 350px), 100%);
    justify-content:flex-start;
    /* No padding at all, not just none at the sides. The 16px above and below
       is there to space cells that share a row; here it only stood the band
       34px taller than the logo in it. The live band is exactly as tall as its
       mark plus the tier padding. */
    padding:0;
    height:auto;
  }
  .sponsor-tier.plat-tier .logos-col,
  .sponsor-tier.plat-tier .logo-flow{ justify-content:flex-start; }
  /* A ceiling on the mark, whatever the tier is set to.
     The gold file the office uploads is a sixteen-by-nine canvas with the
     wordmark floating in the middle of it, so the height the band is given goes
     mostly to transparency: at the saved 153 the band stood 242 tall with a
     wordmark no bigger than it is at 120. Held here rather than in the setting
     because the setting has been raised back twice; the live site draws this
     mark 120 tall and 300 wide, and nothing about this band needs more. */
  .sponsor-tier.gold-tier .logo-chip img{
    filter:none; opacity:1;
    /* !important because the shared sizing above carries it; this selector is
       the more specific of the two, so with both marked the ceiling wins. */
    max-height:min(var(--sp-h, 120px), 120px) !important;
    max-width:min(var(--sp-w, 300px), 300px) !important;
  }
  /* multiply is what drops the white box most of these logos are supplied with,
     by blending them into the paper behind the band.

     It needs the paper to actually be the backdrop. While the cells were ruled
     and overlapped by a negative margin, it was not, and every sponsor logo
     rendered as nothing at all — which is why the platinum band alone used to
     carry an isolation:isolate to force a backdrop of its own. With the cells
     gone the backdrop is the band, multiply behaves, and no band needs the
     override: isolating a tile now costs the white boxes coming back, because
     the tile itself has no background to blend into. */
  .logo-chip{ transition:opacity 0.15s !important; }
  .logo-chip img{ mix-blend-mode:multiply; }
  .logo-chip:hover img{ mix-blend-mode:multiply; opacity:1; }
  .sponsor-tier.plat-tier .logo-chip:hover{ background:transparent !important; box-shadow:none !important; }
  .sponsor-tier.plat-tier .plat-logo-link img{ mix-blend-mode:multiply; }

/*
  Watch — one player with the episode list beside it.

  A grid of small players was the old arrangement; it made every recording
  equally small and equally ignorable. One large frame with a list next to it
  reads as a programme instead, and picking an episode swaps the frame rather
  than the page, so the list keeps its place.

  A single episode keeps the full-width player and no list is drawn.
*/
.ep-layout{
  display: grid;
  grid-template-columns: 7fr 3fr;
  gap: 0 28px;
  align-items: start;
}
.ep-layout--solo{ grid-template-columns: 1fr; }

.ep-list-head{
  font-family: 'ABCNormal', sans-serif; font-size: 12px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: 14px;
}
/* Scrolls rather than stretching the section over three screens. The cap here
   is the stacked-layout one and the starting value before the script runs; on a
   wide screen the script replaces it with the player's own height, which is the
   only way the two columns finish on the same line at every width. */
.ep-list{
  display: flex; flex-direction: column;
  max-height: 492px; overflow-y: auto;
  border-top: 1px solid var(--line);
}

.ep-item{
  display: flex; gap: 14px; align-items: center; width: 100%;
  padding: 12px 10px 12px 13px;
  border: 0; border-bottom: 1px solid var(--line);
  border-left: 3px solid transparent;
  background: none; text-align: left; font-family: inherit; cursor: pointer;
  transition: background 0.15s;
}
.ep-item:hover{ background: var(--concrete); }
.ep-item:focus-visible{ outline: 2px solid var(--green); outline-offset: -2px; }
.ep-item.active{ border-left-color: var(--green); background: var(--concrete); }

.ep-thumb{
  position: relative; width: 108px; height: 61px; flex: 0 0 auto;
  background: var(--ink); overflow: hidden; border-radius: 3px;
}
.ep-thumb img{ width: 100%; height: 100%; object-fit: cover; display: block; }
/* Only the episode playing carries the marker, so the list says where you are. */
.ep-play{
  position: absolute; inset: 0; display: none;
  align-items: center; justify-content: center; background: rgba(19, 32, 27, 0.32);
}
.ep-item.active .ep-play{ display: flex; }
.ep-play > span{
  width: 26px; height: 26px; border-radius: 50%; background: var(--green);
  display: flex; align-items: center; justify-content: center;
}
.ep-play > span::before{
  content: ""; margin-left: 2px;
  border-left: 8px solid var(--paper);
  border-top: 5px solid transparent; border-bottom: 5px solid transparent;
}

.ep-meta{ min-width: 0; display: flex; flex-direction: column; }
.ep-cat{
  font-family: 'ABCNormal', sans-serif; font-size: 10.5px; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--green-deep); font-weight: 600;
}
.ep-title{ font-size: 16px; font-weight: 700; color: var(--ink); margin-top: 3px; line-height: 1.2; }
.ep-item.active .ep-title{ color: var(--green-deep); }

/* Below 900px a three-tenths column is too narrow to read a title in, so the
   list moves under the player and becomes a shorter scrolling strip. */
@media (max-width: 900px) {
  .ep-layout{ grid-template-columns: 1fr; gap: 24px; }
  .ep-list{ max-height: 380px; }
}
@media (max-width: 560px) {
  .ep-thumb{ width: 88px; height: 50px; }
  .ep-title{ font-size: 14.5px; }
  .ep-list{ max-height: 290px; }
}

/* Where the home page differs from the shared furniture
   ---------------------------------------------------------------------------
   layout.css carries the header, footer and buttons for every page. These three
   are the home page's own, and they are here rather than there because the hero
   sits on a photograph: the filled button has to be light on dark, the opposite
   way round from every other page. */
.logo{ font-family:'ABCNormal',sans-serif; font-weight:700; font-size:19px; letter-spacing:-0.01em; display:flex; align-items:baseline; gap:8px; }
.btn-fill{ background:var(--paper); color:var(--ink); border-color:var(--paper); }
.btn-fill:hover{ background:#a01c1c; border-color:var(--ink); color:var(--paper); }

/* The home page writes .wrap and .header-wrap together in its own breakpoints,
   which lands after layout.css and would otherwise undo the shared rule that
   leaves room for the hamburger. Restated here so it still wins. */
@media (max-width:980px){
  .header-wrap{ position:relative; padding-right:48px !important; }
}

/* The sister event's mark is drawn much wider than it is tall — 5503 by 1140,
   nearly five to one — so at the same height as the two beside it, it runs
   almost twice their width and takes over the row. The live site caps it at
   half its card, and this does the same by naming the card that carries a date
   — the one holding a sister event rather than a co-located show — so the cap
   follows the dates wherever the office puts them. */
.ko-card--dated .ko-well img{ max-width:50%; }

/* Doors & Windows sets the About paragraphs further apart and closes the gap
   under the sister event's date. Asked for by name; the two sisters keep the
   shared figures above. Only the measurement that differs is stated, so a
   later change to the colour or the size still reaches all three. */
body[data-site="doors"] .ab-col p{ margin-bottom:20px; }
body[data-site="doors"] .ko-card .se-date{ padding-bottom:10px; }
/* The figure's caption sits straight under it here, with no step of its own,
   and its lines a shade further apart. Asked for by name; the sisters keep the
   2px above and the 1.5 line height. */
body[data-site="doors"] .about-stat .st-label{ margin-top:0; line-height:1.6; }
/* The sister event's well is asked to be 483.686 wide, which is what makes the
   50% cap above land on 241.84. Guarded with min() because the column it sits
   in is narrower than that until the window is very wide — 348.7 at 1440 — and
   a fixed width would simply run out of the panel. Where there is room it takes
   the figure; where there is not it takes the column. */
.ko-card--dated .ko-well{ width:min(483.686px, 100%); }
/* Glass Technology closes the gap under the sister event's date. Asked for by
   name; Doors & Windows sets its own above and Aluminium Extrusions has no
   dated card to show. Only the measurement that differs is stated — the size,
   weight and rule still come from the shared block. */
body[data-site="glass"] .ko-card .se-date{ padding-bottom:13px; }

/* The first cell in each hero row gives up its left padding, so DATES and the
   200+ figure begin on the same line as the eyebrow, the headline, the lede and
   the buttons above them — 48 rather than 76. Every cell after the first keeps
   its 28px on both sides, because those sit against a rule rather than against
   the edge of the page.

   This is what the live Doors & Windows draws: its first bar cell is padded
   20px 28px 20px 0 and its first figure cell 22px 28px 22px 0.

   All three sites, asked for by name. Glass Technology's own live site indents
   both by the full 28px, so this is the one place the family is deliberately
   tidier than the site it was drawn from. */
.hero-bar-cell:first-child,
.hero-num-cell:first-child{ padding-left:0; }
