/* DigiDoe mobile island. Hand written on purpose: CSS is the only thing in this feature that could
   ever leak to desktop, so every rule stays auditable rather than being emitted by a bundler.

   THE SAFETY CONTRACT, and it is the reason this file is shaped the way it is:
   every rule below sits inside @media (max-width:760px) AND under html.dd-m-react. The flag class
   is added by React from an effect, so it only exists once a tree has actually committed. Desktop
   never matches the media query. A phone with no JS, a blocked bundle, or an island that threw
   never gets the class. In all of those cases the legacy mobile site renders exactly as it does
   today, because nothing in dd-shell.css or alt-home.css was edited or deleted to make room.

   Tokens are measured off the Otabek comps at a 393px frame. Values marked PENDING are waiting on
   a designer answer and are one line changes. */

/* TOKENS. Every value below is lifted from the official kit at
   web/design language/digidoe-ui-kit.html, which is the source of truth and which resolved two
   things this island had been sampling by eye: --primary is #f37f00 (so the comp orange is correct
   and #F5921E elsewhere in the CSS is drift), and the promo bar ground is not a bespoke colour, it
   is --ink #121212.

   The kit's names are NOT used bare. dd-shell.css already declares --ink, so declaring kit names at
   :root would silently reassign a desktop variable, which is exactly the class of leak this whole
   feature is built to avoid. Prefixed instead, with the kit name each one mirrors. Promote to a
   shared tokens.css only as a deliberate desktop change, never as a side effect of mobile work. */
:root{
  --ddm-accent:#f37f00;        /* kit --primary */
  /* kit --on-primary. The comp draws WHITE label text on the orange pill, but white on #f37f00
     measures 2.68:1, which fails WCAG AA for 15px semibold (4.5:1 required). This near black is the
     kit's own answer and measures about 7.9:1. The project already made this call once: state.md
     records "AA-safe button text via kit's own --on-primary". Kept dark deliberately, because on a
     regulated financial promotion the legal floor outranks the comp. Flag for the brand owner. */
  --ddm-on-primary:#1a1200;
  --ddm-rail-h:52px;           /* 44px control + 4px padding top and bottom */
  --ddm-accent-hover:#d96e00;  /* kit --primary-hover */
  --ddm-ink:#121212;           /* kit --ink */
  --ddm-soft:#5c5f66;          /* kit --text-2 */
  --ddm-line:#e7e5de;          /* kit --border */
  --ddm-page:#ffffff;          /* kit --canvas */
  --ddm-surface-2:#f4f3f0;     /* kit --surface-2 */
  /* Sampled flat from Announcement bar grey.png as #121212, which turned out to BE kit --ink. The
     file is named "grey"; the pixels are near black. */
  --ddm-promo-bg:var(--ddm-ink);
  --ddm-promo-fg:#f4f5f8;      /* kit --on-ink-1 */
  --ddm-pad:18px;              /* card edge to frame edge, and the promo bar's own gutter */
  --ddm-gut:34px;              /* page level gutter: legal line, hairlines, tile rows, footer */
  --ddm-gut-hero:50px;         /* hero heading and body sit further in than everything else */
  --ddm-btn-h:47px;            /* measured */
  --ddm-nav-h:64px;            /* measured */
  --ddm-promo-h:57px;          /* bar rect inside the 61px export canvas (1px transparent margin) */
  --ddm-font:"Hanken Grotesk",system-ui,-apple-system,sans-serif;
  --ddm-nav-font:Inter,system-ui,-apple-system,sans-serif;
}

/* ===========================================================================================
   CHROME. Rebuilt against the Aug comps; every number below is in mobile-app/src/chrome-spec.md
   and was sampled from the comp pixels rather than estimated.

   The July version of this block was authored without an open-drawer comp ("the Otabek comps show
   the hamburger CLOSED only"). There are two now, one per lane, and they changed three things:
   the lane control moved INTO the bar, the drawer's IA is Who-you-are / What-you-need rather than
   the site's footer, and the CTAs are NOT pinned to the viewport bottom.
   =========================================================================================== */
@media (max-width:760px){

  /* PROGRESSIVE REPLACEMENT. Hide only what the island has actually rebuilt, so a phase that has
     done the chrome and not the body never renders a nav above an empty page.

     THE SELECTORS BELOW ARE A CLASS LIST, NOT A GUESS. Measured at 393 with the island mounted:
     anything still visible as a body child that the island ALSO draws renders twice, and that
     double image is the whole of "this does not look like the comps". Two survivors were found
     and are fixed here.

       .promo did not match the real element. The legacy announcement bar ships as
       <div class="ribbon dd-promo">, so the old rule missed it on every page and the island's own
       .ddm-promo stacked underneath it. That is the phantom second banner.

       footer.site leaked on companies only (1018px of duplicate footer). index and individuals
       already resolved to island-height == body-height, so their footers come from the island;
       hiding the legacy one is safe there and necessary here. */
  html.dd-m-react body > header.site,
  html.dd-m-react body > .alt-scrim,
  html.dd-m-react body > .promo,
  html.dd-m-react body > .ribbon.dd-promo,
  html.dd-m-react body > footer.site,
  html.dd-m-react body > .cookiebar ~ header.site{display:none!important}

  .ddm{position:relative;z-index:2}

  /* --- announcement bar. 59px, one centred row, 18px left inset for the badge. Three variants
     drawn and all three kept; the ground, body and link colours are the only difference. --- */
  .ddm-promo{
    display:flex;align-items:center;gap:8px;min-height:59px;padding:0 18px;
    font-size:13px;line-height:1.25;
  }
  .ddm-promo.is-light {background:#ece9de;color:var(--ddm-ink)}
  .ddm-promo.is-black {background:#121212;color:#fff}
  .ddm-promo.is-orange{background:var(--ddm-accent);color:#fff}

  .ddm-promo-pill{
    flex:0 0 auto;display:inline-flex;align-items:center;height:24px;padding:0 11px;
    border-radius:999px;font-size:11px;font-weight:700;letter-spacing:.03em;
    background:var(--ddm-accent);color:#fff;
  }
  .ddm-promo.is-orange .ddm-promo-pill{background:#fff;color:var(--ddm-accent)}

  .ddm-promo-text{flex:0 1 auto;font-style:italic;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* padding plus an equal negative margin: the hit area grows to 44 while the painted row keeps the
     comp's geometry. The alternative, growing the control itself, would break a bar the designer
     drew at 59px. */
  .ddm-promo-cta{
    flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;margin-left:auto;
    padding-block:14px;margin-block:-14px;
    font-weight:700;text-decoration:underline;text-underline-offset:3px;color:var(--ddm-accent);
  }
  .ddm-promo.is-orange .ddm-promo-cta{color:#fff}
  .ddm-promo-x{
    flex:0 0 auto;display:grid;place-items:center;width:44px;height:44px;margin-right:-12px;
    background:none;border:0;color:inherit;cursor:pointer;
  }

  /* --- bar. 393x69 with a 1px hairline. Logo at 24, lane control 223x40 centred, burger 27 from
     the right edge. No CTA: the comp has none, the sticky pill carries it. --- */
  .ddm-bar{
    position:sticky;top:0;z-index:40;
    display:flex;align-items:center;justify-content:space-between;
    height:69px;padding:0 24px;background:#fff;border-bottom:1px solid #e6e6e6;
  }
  .ddm-brand{display:flex;align-items:center;min-height:44px}
  .ddm-brand img{display:block;height:32px;width:auto}

  .ddm-lane{
    position:absolute;left:50%;transform:translateX(-50%);
    display:flex;align-items:center;width:223px;height:40px;padding:2px;
    background:#f4f3f0;border-radius:20px;
  }
  .ddm-lane-i{
    flex:1 1 0;display:grid;place-items:center;height:36px;border-radius:18px;
    font-size:14px;font-weight:500;color:#888;text-decoration:none;
  }
  .ddm-lane-i.on{background:#fff;color:#121212;font-weight:600}

  .ddm-burger{
    display:grid;place-items:center;width:44px;height:44px;margin-right:-9px;
    background:none;border:0;color:#4d4d4d;cursor:pointer;
  }

  /* --- drawer. Full screen, so no scrim: a scrim under a full screen panel is covered at every
     pixel, can never be seen and can never be clicked. --- */
  html.dd-m-drawer,html.dd-m-drawer body{overflow:hidden}
  .ddm-drawer{
    position:fixed;inset:69px 0 0;z-index:35;background:#fff;
    overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  }
  .ddm-drawer::-webkit-scrollbar{width:0;height:0}
  .ddm-drawer-body{padding:0 0 38px}

  .ddm-dgroup{padding-top:22px}
  .ddm-drule{border:0;border-top:1px solid #e6e6e6;margin:22px 0 0}
  .ddm-dhead{
    margin:0 0 4px;padding:0 44px;
    font-size:11px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:#121212;
  }
  .ddm-dnote{margin:0 0 10px;padding:0 44px;max-width:31ch;font-size:13px;line-height:1.45;color:#6b6b76}

  .ddm-drow{
    display:flex;align-items:center;gap:10px;
    min-height:51px;margin:0 32px;padding:0 12px;border-radius:15px;
    font-size:15px;color:#121212;text-decoration:none;
  }
  .ddm-drow.on{background:#f3f3f1}
  .ddm-drow-t{flex:1 1 auto}
  .ddm-dbadge{
    flex:0 0 auto;display:inline-flex;align-items:center;height:20px;padding:0 8px;
    border-radius:999px;background:var(--ddm-accent);color:#fff;
    font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  }

  .ddm-dsmall{margin:16px 0 0;padding:0 44px;font-size:13px;color:#6b6b76;line-height:1.6}
  .ddm-dsmall a{
    color:#6b6b76;text-decoration:none;display:inline-block;
    padding-block:14px;margin-block:-8px;line-height:16px;
  }

  /* --- currency. The control does not move when it opens; the list is inserted beneath it and
     pushes the CTAs down. Fixed height with a hard clip, as drawn. --- */
  .ddm-ccy{margin:22px 32px 0}
  .ddm-ccy-btn{
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    width:100%;height:46px;padding:0 18px;border-radius:23px;
    background:#fff;border:1px solid #888;color:#121212;font-size:15px;cursor:pointer;
  }
  .ddm-ccy-list{
    max-height:272px;overflow-y:auto;overscroll-behavior:contain;
    margin:10px 0 0;padding:0;list-style:none;
  }
  .ddm-ccy-list::-webkit-scrollbar{width:0}
  .ddm-ccy-row{
    display:flex;align-items:center;gap:0;width:100%;height:47px;padding:0 17px;
    border:0;border-radius:15px;background:none;text-align:left;cursor:pointer;
  }
  .ddm-ccy-row.on{background:#f6f6f3}
  .ddm-ccy-code{flex:0 0 46px;font-size:15px;font-weight:600;color:#121212}
  .ddm-ccy-label{flex:1 1 auto;font-size:15px;color:#666}

  /* --- CTAs. 329x47 pills. NOT pinned: the comp puts them at the end of the scroll with about
     38px after Contact sales, and the currency list pushes them a further 281px down. --- */
  .ddm-dctas{display:flex;flex-direction:column;gap:17px;margin:33px 32px 0}
  .ddm-btn{
    display:grid;place-items:center;min-height:47px;padding:0 20px;border-radius:24px;
    font-size:15px;font-weight:600;text-decoration:none;
  }
  .ddm a.ddm-btn-primary,
  .ddm button.ddm-btn-primary{background:var(--ddm-accent);color:#fff}
  .ddm a.ddm-btn-outline{background:#fff;border:1px solid #121212;color:#121212}
  .ddm a.ddm-btn-text{
    background:none;border:0;color:#6b6b76;font-weight:500;min-height:44px;margin-top:17px;
  }

  /* --- sticky pill. A 329x47 button inside a 356x73 white-at-90% capsule with a 32px backdrop
     blur, 14px above the viewport bottom. The comp draws it in isolation; the collision with the
     cookie bar is resolved in Chrome.jsx (the pill stands down while consent is showing) and the
     chatbot button is lifted here so nothing is ever unreachable. --- */
  .ddm-sticky{
    position:fixed;left:50%;transform:translateX(-50%);bottom:calc(14px + env(safe-area-inset-bottom,0px));
    z-index:45;width:356px;max-width:calc(100% - 24px);padding:13px;
    border-radius:36px;background:rgba(255,255,255,.9);
    -webkit-backdrop-filter:blur(32px);backdrop-filter:blur(32px);
  }
  .ddm-sticky .ddm-btn{width:100%}
  html.dd-m-react .dd-fab,
  html.dd-m-react .chatbot-fab,
  html.dd-m-react [class*=fab]{bottom:calc(101px + env(safe-area-inset-bottom,0px))!important}

  .ddm :focus-visible{outline:2px solid var(--ddm-accent);outline-offset:2px;border-radius:4px}
  .ddm-drawer :focus-visible{outline:2px solid var(--ddm-accent);outline-offset:2px}
}

@media (max-width:760px) and (prefers-reduced-motion:no-preference){
  .ddm-drawer{animation:ddm-in .22s cubic-bezier(.16,1,.3,1) both}
}
/* ===========================================================================================
   PAGE BODY. Separate block so the chrome above stays readable.

   Gated on html.dd-m-body, which Page adds from its own effect. That is one step stricter than the
   chrome's flag: the legacy <main> is only hidden once React has committed a body to replace it, so a
   throw in the section renderer leaves the current mobile page standing instead of blanking it.

   Geometry is the comps', via tools/comp-layout.py: page gutter 34, hero copy 50, tile card copy 58
   (a card at 34 with 24 of internal padding), CTA pills about 296 wide and centred.
   =========================================================================================== */
@media (max-width:760px){

  /* Sections, NOT main itself. These pages ship no closing </main> tag (grep '</main>' returns 0 in
     all of them), so the browser auto closes main at </body> and the FOOTER ends up nested inside
     main#main. Hiding main therefore also hid the footer, which is exactly what the design QA pass
     caught. Targeting the sections leaves the legacy footer standing.
     The missing </main> is a real bug in the pages, not just an inconvenience here, and it is worth
     fixing on the desktop side. Doing that would reparent the footer to body, so it needs its own
     gate run rather than being folded into mobile work. */
  html.dd-m-body body > main#main > section{display:none!important}

  /* The legacy footer is deliberately still in play. It is already left ranged at the 34 gutter,
     which is what the comps show, so rebuilding it would be churn for no visible gain. */

  /* No background here. body already paints --ddm-page, so this only duplicated it, and because the
     audience rail's items overflow their container by 8px the opaque ground of the first section
     painted straight over the bottom of the pill. Hit testing put .ddm-hero on top at that edge even
     with the rail positioned. Removing the redundant fill removes the covering at its cause. */
  .ddm-main{display:block}

  /* Reset first. The legacy stylesheets style bare element selectors, including section, and the
     island renders real <section> elements, so each one silently inherited a white fill. That fill
     painted over the bottom of the audience rail and read as the toggle being sliced off. Anything
     in the island that wants a ground states it explicitly below (.ddm-dark, .ddm-hero-card). */
  .ddm .ddm-sec{background:transparent}

  .ddm-sec{padding:44px var(--ddm-gut) 0}
  .ddm-sec:last-child{padding-bottom:48px}
  .ddm-a-c{text-align:center}
  .ddm-a-l{text-align:left}

  /* Hero is the one section the comps do NOT centre: heading and body measured left at x=50. */
  .ddm-hero{padding:28px var(--ddm-gut-hero) 0}
  /* Spacing read off the comp rather than eyeballed. Heading lines step 42px and end about y=397,
     body opens at y=441, so the heading needs roughly 40 beneath it, not the 14 the shared rule
     gives every other section. */
  .ddm-hero .ddm-h{font-size:34px;line-height:1.22;letter-spacing:-.01em;max-width:11ch;margin-bottom:40px}
  .ddm-hero .ddm-b:first-of-type{font-size:15px}
  /* The hero is left ranged but its legal line is centred in the comp, the one place inside a single
     section where the two alignments sit together. */
  .ddm-legal{text-align:center;font-size:12px;line-height:1.45;margin-left:auto;margin-right:auto}

  .ddm-h{
    margin:0 0 14px;font-weight:300;font-size:29px;line-height:1.2;
    letter-spacing:-.008em;color:var(--ddm-ink);text-wrap:balance;
  }
  .ddm-a-c .ddm-h{margin-left:auto;margin-right:auto;max-width:17ch}
  .ddm-b{margin:0 0 12px;font-size:14px;line-height:1.5;color:var(--ddm-soft);max-width:40ch}
  .ddm-a-c .ddm-b{margin-left:auto;margin-right:auto;max-width:40ch}

  .ddm-media{display:block;max-width:100%;height:auto;margin:18px auto 0;border-radius:16px}

  /* ---------------------------------------------------------------- tile row */
  /* Negative margin then matching scroll padding: the rail bleeds to the screen edge so a card can
     be half visible at the right, which is the affordance that says "this scrolls", while the first
     card still lines up on the 34 gutter with everything above it. */
  .ddm-row-wrap{margin-top:20px}
  .ddm-row{
    display:flex;gap:12px;margin:0 calc(var(--ddm-gut) * -1);padding:2px var(--ddm-gut) 4px;
    list-style:none;overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;scroll-padding-inline-start:var(--ddm-gut);
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
  }
  .ddm-row::-webkit-scrollbar{display:none}
  /* Percentage of the rail rather than a fixed 296, so a 320 screen keeps the peek that signals the
     row scrolls. 91%, not 82%: the rail's content box is the frame minus both gutters (325 at 393),
     and 91% of that lands on the comp's 296 exactly, where 82% undershot to 267. */
  .ddm-tile{
    flex:0 0 min(296px,91%);scroll-snap-align:start;
    background:var(--ddm-surface-2);border-radius:16px;padding:24px;
  }
  .ddm-row.ddm-a-c .ddm-tile{text-align:center}
  .ddm-row.ddm-a-l .ddm-tile{text-align:left}
  .ddm-tile img{display:block;max-width:100%;height:auto;border-radius:10px;margin-bottom:12px}
  .ddm-tile-h{margin:0 0 8px;font-size:17px;font-weight:600;line-height:1.3;color:var(--ddm-ink)}
  .ddm-tile-p{margin:0 0 8px;font-size:14px;line-height:1.5;color:var(--ddm-soft)}
  .ddm-tile-p:last-child{margin-bottom:0}
  /* companies.html seg-rows: a per-card CTA the comp draws as a plain arrow link under the copy, not
     a second button. Reuses the section's own link colour rather than inventing a new one.
     min-height, not just padding: the 13px label alone boxes to 21px in mobile-sweep's tap-target
     probe, under the 24px WCAG 2.5.8 floor every other control on the island already clears. */
  .ddm-tile-cta{display:inline-flex;align-items:center;min-height:24px;margin-top:2px;font-size:13px;font-weight:600;color:var(--ddm-accent)}


  /* Tag pills and stepped ordinals, restored. These carry real approved copy the extractor used to
     drop, and their absence is worth about 15 percent of a card row's height on the pages that use
     them. Recovering the content is the fix; padding the gap would have been the fake one. */
  .ddm-list{margin:22px 0 0;text-align:left}
  .ddm-list-h{margin:0 0 10px;font-size:16px;font-weight:700;color:var(--ddm-ink)}
  .ddm-list ul{margin:0;padding:0 0 0 18px;list-style:disc}
  .ddm-list li{margin:0 0 8px;font-size:15px;line-height:1.5;color:var(--ddm-soft)}

  .ddm-tile-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
  .ddm-tag{
    display:inline-flex;align-items:center;min-height:24px;padding:0 10px;border-radius:999px;
    background:var(--ddm-wash,#f6f3ef);color:var(--ddm-soft);
    font-size:12px;font-weight:600;letter-spacing:.01em;
  }
  .ddm-tile-num{
    display:block;margin-bottom:10px;font-size:34px;font-weight:250;line-height:1;
    color:var(--ddm-accent);opacity:.34;font-variant-numeric:tabular-nums;
  }  .ddm-ic{display:block;width:40px;height:40px;margin-bottom:14px}
  .ddm-row.ddm-a-c .ddm-ic{margin-left:auto;margin-right:auto}
  .ddm-ic svg{width:100%;height:100%;display:block}

  .ddm-dots{display:flex;gap:2px;justify-content:center;margin-top:4px}
  /* The dot drawn stays 7px; the button around it is 44 tall so it is reachable with a thumb. */
  .ddm-dot{
    width:28px;height:44px;padding:0;border:0;background:none;cursor:pointer;
    display:grid;place-items:center;
  }
  .ddm-dot::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--ddm-line)}
  .ddm-dot.on::before{background:var(--ddm-accent)}

  /* --------------------------------------------------------------- accordion */
  .ddm-acc{margin-top:18px;text-align:left}
  .ddm-acc-row{border-top:1px solid var(--ddm-line)}
  .ddm-acc-row:last-child{border-bottom:1px solid var(--ddm-line)}
  .ddm-acc-q{
    width:100%;min-height:56px;display:flex;align-items:center;justify-content:space-between;
    gap:14px;background:none;border:0;padding:14px 0;cursor:pointer;
    font-size:16px;font-weight:500;text-align:left;color:var(--ddm-ink);font-family:inherit;
  }
  .ddm-acc-sign{font-size:22px;font-weight:300;color:var(--ddm-accent);line-height:1}
  .ddm-acc-a{padding:0 0 16px}
  .ddm-acc-a p{margin:0 0 10px;font-size:14px;line-height:1.55;color:var(--ddm-soft)}

  /* -------------------------------------------------- tell me about linklist */
  .ddm-links{list-style:none;margin:6px 0 0;padding:0;text-align:left}
  .ddm-links li{border-bottom:1px solid var(--ddm-line)}
  .ddm-links a{
    display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:56px;
    font-size:16px;font-weight:500;color:var(--ddm-accent);
  }
  .ddm-links svg{flex:0 0 auto}

  .ddm-badges{display:flex;gap:12px;justify-content:center;align-items:center;margin-top:20px;flex-wrap:wrap}
  /* max-width:none defeats the global img rule: these badges carry width/height attributes and were
     rendering at wildly different sizes, one huge and one squashed. */
  .ddm-badges img{display:block;height:40px;width:auto;max-width:none}

  /* CTAs: centred pills inset to roughly the hero gutter, never full bleed. */
  .ddm-ctas{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:22px}
  .ddm-ctas .ddm-btn{width:min(296px,100%)}

}


/* ===========================================================================================
   Hero art, audience switch, chips, testimonial, tabs.
   =========================================================================================== */
@media (max-width:760px){

  /* Audience switch. A grey rail with a white raised pill on the current lane, the same idiom the
     desktop nav uses, so the two read as one product rather than two. */
  /* position+z-index and a real bottom margin, both deliberate. .ddm-main paints an opaque page
     ground and begins before this control's box ends, so without them the section below drew over
     the bottom of the pill and the toggle read as sliced off along its lower edge. */
  /* min-height is explicit, and it has to be. The items are 44 tall inside 4px of padding, so the
     rail paints 52, but its in-flow height resolved to 30 (a 14px line box plus padding) and the
     items overflowed downward. The next section paints an opaque ground, so it covered the bottom of
     the pill and the toggle read as sliced off. 52 = 44 item + 8 padding. */
  .ddm-seg{
    position:relative;z-index:1;
    display:flex;align-items:center;gap:4px;height:52px;
    margin:12px var(--ddm-gut) 14px;padding:4px;
    background:var(--ddm-surface-2);border-radius:999px;
  }
  .ddm-seg-i{
    flex:1 1 0;min-height:44px;display:flex;align-items:center;justify-content:center;
    border-radius:999px;font-family:var(--ddm-nav-font);font-size:14px;font-weight:600;
    color:var(--ddm-soft);
  }
  .ddm-seg-i.on{background:var(--ddm-page);color:var(--ddm-ink);box-shadow:0 1px 3px rgba(18,18,18,.12)}

  /* Hero photo card. The scrim is not decoration: the comp sets white type over a photograph, and
     without a wash the contrast fails wherever the image happens to be light. */
  .ddm-hero{padding-left:var(--ddm-pad);padding-right:var(--ddm-pad)}
  .ddm-hero-card{
    border-radius:24px;padding:34px 32px 30px;
    background:var(--ddm-surface-2);
  }
  .ddm-hero-card.has-art{
    background:
      linear-gradient(180deg,rgba(12,12,14,.42) 0%,rgba(12,12,14,.72) 100%),
      var(--ddm-hero-img) center/cover no-repeat,#16151A;
  }
  .ddm-hero-card.has-art .ddm-h{color:#fff}
  .ddm-hero-card.has-art .ddm-b{color:rgba(255,255,255,.86)}
  .ddm-hero-card.has-art .ddm-btn-text{color:#fff;text-decoration:underline;text-underline-offset:3px}
  /* Comp puts the two pills 63px apart on a 47px pill, so 16 between them. */
  .ddm-hero .ddm-ctas{align-items:stretch;margin-top:26px;gap:16px}
  /* The legal line sits OUTSIDE the card on the page ground, and on the 34 gutter rather than the
     hero's own 18, so it takes the difference back as padding. */
  .ddm-hero .ddm-legal{
    margin:38px auto 0;padding:0 16px;max-width:46ch;color:var(--ddm-soft);
  }

  /* chips */
  .ddm-chips{
    display:flex;flex-wrap:wrap;gap:8px;justify-content:center;
    list-style:none;margin:16px 0 0;padding:0;
  }
  .ddm-a-l .ddm-chips{justify-content:flex-start}
  .ddm-chips li{
    padding:7px 13px;border-radius:999px;border:1px solid var(--ddm-line);
    font-size:13px;font-weight:500;color:var(--ddm-soft);
  }

  /* testimonial */
  .ddm-quote{
    margin:20px 0 0;padding:26px 24px 22px;border-radius:18px;
    background:var(--ddm-surface-2);text-align:left;position:relative;
  }
  .ddm-qmark{
    display:block;font-size:44px;line-height:.7;color:var(--ddm-accent);
    font-family:var(--ddm-font);margin-bottom:6px;
  }
  .ddm-quote blockquote{margin:0;font-size:16px;line-height:1.5;color:var(--ddm-ink)}
  .ddm-quote figcaption{margin-top:14px;font-size:13px;color:var(--ddm-soft)}

  /* tabs */
  .ddm-tabs-wrap{margin-top:18px}
  /* same explicit min-height as the audience rail above, for the same reason */
  .ddm-tabs{
    display:flex;align-items:center;gap:4px;height:52px;padding:4px;
    background:var(--ddm-surface-2);border-radius:999px;
  }
  .ddm-tab{
    flex:1 1 0;min-height:44px;border:0;background:none;cursor:pointer;border-radius:999px;
    font-family:var(--ddm-nav-font);font-size:14px;font-weight:600;color:var(--ddm-soft);
  }
  .ddm-tab.on{background:var(--ddm-page);color:var(--ddm-ink);box-shadow:0 1px 3px rgba(18,18,18,.12)}
  .ddm-tabs-note{margin:12px 0 0;font-size:12px;line-height:1.45;color:var(--ddm-soft)}
}


@media (max-width:760px){

  /* App fold. The comp makes this a black card, the only inverted block on the page apart from the
     promo bar, so it uses the same --ddm-ink ground rather than a second near black. */
  .ddm .ddm-sec.ddm-dark{
    margin:44px var(--ddm-pad) 0;padding:36px 28px 32px;
    background:var(--ddm-ink);border-radius:24px;
  }
  .ddm-dark .ddm-h{color:#fff}
  .ddm-dark .ddm-b{color:rgba(255,255,255,.82)}
  .ddm-dark .ddm-media{margin-top:24px;border-radius:14px}

  /* The chat launcher and the sticky CTA are injected by dd-shell.js for the desktop/legacy mobile
     page. Neither appears in the comps, and the launcher was sitting on top of the content as a
     floating orange ringed circle. Hidden only while the island owns the page, and only here, so the
     legacy mobile keeps them if the island never mounts. */
  html.dd-m-body body > .dd-bot,
  html.dd-m-body body > .ddbot,
  html.dd-m-body body > .ddbot-fab,
  html.dd-m-body body > .ddbot-panel,
  html.dd-m-body body > .stickycta,
  html.dd-m-body body > [class*="ddbot"],
  html.dd-m-body body > [class*="stickycta"]{display:none!important}
}


/* ===========================================================================================
   Footer. Geometry from the comp PDF: everything left ranged on the 34 gutter, column headings at
   y=8403 / 8656 / 8942 with their links stepping 33px, the certification strip at 9384 and the
   regulatory paragraphs from 9444.
   =========================================================================================== */
@media (max-width:760px){

  /* The legacy footer is a child of main#main, because these pages never close <main>. That is why
     it is targeted here rather than as a child of body. */
  /* Hidden whenever the island mounted, not only when the body was rebuilt: the comp footer ships on
     every page from phase 1, because the extractor already has footer data for all 29 and the legacy
     mobile footer renders four fewer links than the comp's three columns. */
  html.dd-m-foot body > main#main > footer{display:none!important}

  /* Measured off companies/fold-08 and fold-09, which are byte-identical to teams' pair, so this is
     one footer for all 30 pages. Total comp height 1,642: a 1,058 band of wordmark, tagline, store
     badges and three stacked link columns, then a 584 band of certification and legal.

     Cream ground, and it is the only band on the page that is not white. Columns STACK, one fully
     after another; they are not a row. Links step 33. No social row: the comp has none, and the rule
     is that what the designer did not draw does not exist on mobile. */
  .ddm-foot{
    padding:24px var(--ddm-gut) 9px;text-align:left;background:#f0eee7;margin-top:0;border-top:0;
  }
  .ddm-foot-logo{display:block;height:40px;width:auto;margin:0 0 20px}
  .ddm-foot-tag{margin:0 0 32px;max-width:32ch;font-size:14px;line-height:1.45;color:var(--ddm-soft)}

  .ddm-foot-apps{display:flex;gap:9px;margin-bottom:30px}
  .ddm-foot-apps img{display:block;height:42px;width:auto;max-width:none}

  .ddm-foot-col{display:flex;flex-direction:column;margin-bottom:35px}
  .ddm-foot-h{
    margin:0 0 6px;font-family:var(--ddm-nav-font);font-size:16px;font-weight:700;
    color:#1a1a1a;
  }
  .ddm-foot-col a{
    display:flex;align-items:center;min-height:33px;
    font-size:14px;color:#8f8f8f;
  }

  .ddm-foot-rule{border:0;border-top:1px solid var(--ddm-line);margin:3px 0 15px}

  /* Badge artwork is never rescaled non-uniformly, recoloured or cropped: the ISO usage rules treat
     the mark as fixed artwork, so only the box around it is allowed to change. The comp sets the pair
     at about 156 wide and 200 tall, which is the artwork's own aspect, so this scales it evenly. */
  .ddm-foot-certs{margin:0 0 30px}
  .ddm-foot-badges{display:flex;gap:18px;align-items:flex-start}
  /* Fit, not fixed height: sizing by height alone made the pair 418 wide on a 361 column, which only
     showed up once the footer rendered without a clipping ancestor. object-fit:contain keeps the
     scale uniform and crops nothing, which is what the ISO usage rules require. */
  .ddm-foot-badges img{
    display:block;height:auto;width:auto;max-height:200px;max-width:calc(50% - 9px);
    object-fit:contain;
  }
  .ddm-foot-cap{margin:28px 0 0;max-width:34ch;font-size:13px;line-height:1.5;color:var(--ddm-soft)}

  .ddm-foot-legal p{margin:0 0 17px;font-size:13px;line-height:1.55;color:#79766e}
  .ddm-foot-legal a{color:var(--ddm-accent);text-decoration:underline;text-underline-offset:2px}
  .ddm-foot-legal p:last-child{margin-bottom:0}
}


@media (max-width:760px){
  /* App fold interior. The phone screenshot closes the card and is allowed to bleed past the card's
     bottom padding, which is how the comp seats it: the device reads as rising out of the black
     block rather than floating inside a box. overflow:hidden on the card clips it to the radius. */
  .ddm-sec.ddm-dark{overflow:hidden;padding-bottom:0}
  .ddm-app{display:flex;flex-direction:column;align-items:center}
  .ddm-app-stores{display:flex;gap:12px;justify-content:center;align-items:center;margin-top:22px}
  .ddm-app-stores img{display:block;height:44px;width:auto;max-width:none}
  .ddm-app-phone{
    display:block;width:min(268px,80%);height:auto;margin:30px auto 0;
  }
}


/* === teams === */
@media (max-width:760px){
  /* Every selector below is anchored on something that exists on no other page: an icon's own
     viewBox (Figma canvas coordinates, unique per icon) or the toggle-render image path. That
     keeps this block from ever touching another page's tile rows, even though the classes it
     edits (.ddm-tile, .ddm-row-wrap, .ddm-sec, .ddm-hero-card) are shared component classes the
     rest of the island also uses. Confirmed unique with grep -rl on src/*.html before use. */

  /* hero: comp needs 732 under the bar, this section renders short. Card + legal line get a bit
     more room rather than the type getting bigger, which would fight the 11ch heading wrap. */
  .ddm-hero-card[style*="assets/aug03/hero-meeting.webp"]{padding-top:40px;padding-bottom:48px}
  .ddm-hero:has(.ddm-hero-card[style*="assets/aug03/hero-meeting.webp"]) .ddm-ctas{margin-top:34px}
  .ddm-hero:has(.ddm-hero-card[style*="assets/aug03/hero-meeting.webp"]) .ddm-legal{margin-top:54px}

  /* Apply / Verify / Live, Find your team, One account: REVERTED. These three rows were padded up
     to close a gap that is actually missing content, not missing rhythm, which is dishonest fidelity
     (coordinator correction, this session): the live HTML carries a per-tile `.tile-spec` badge pair
     on each Apply/Verify/Live card and a single tag on each Find-your-team card, plus a corner
     numeral (01/02/03) on the first three and a decorative arrow (→) on the "One account" three,
     and tools/extract-content.mjs's tile collector does not capture any of them (only h/p/img/svg/cta
     reach TileRow). chips:true (teams.js, index 1) is kept because it surfaces REAL extracted words
     (Apply's own badge pair); the shared .ddm-tile/.ddm-row-wrap padding stays on the DEFAULT every
     other page already uses rather than being stretched to hide the other four badge pairs, the
     "Find your team" tags, the numerals and the arrows. Reported to Yuval below, not padded over. */

  /* Open your account online: no existing variant covers "media + heading + body + CTAs in an
     isolated card" with a LIGHT ground -- .ddm-dark is the only card treatment this codebase has
     and it is shared with index's and individuals' real (black) app-fold cards, so this section
     stays on DEFAULT in teams.js and gets its own card built here from scratch, scoped to the
     toggle-render image, which appears on no other page. Padding kept to the codebase's existing
     card convention (compare .ddm-dark's own 36/28/32) rather than stretched further: nothing is
     missing from this section's extracted content (heading, body, image and both CTAs all reach the
     island), so the remaining shortfall against the comp is the image itself reading small at this
     width, which was not verified pixel-for-pixel against the comp and is reported, not padded. */
  .ddm-sec:has(img[src*="teams--toggle-render"]){
    margin:44px var(--ddm-pad) 0;padding:36px 28px 40px;
    background:var(--ddm-surface-2);border-radius:24px;
  }
  .ddm-sec:has(img[src*="teams--toggle-render"]) .ddm-media{
    width:min(220px,60%);margin:0 auto 24px;border-radius:14px;
  }
  .ddm-sec:has(img[src*="teams--toggle-render"]) .ddm-h{margin-bottom:12px}
  .ddm-sec:has(img[src*="teams--toggle-render"]) .ddm-b{margin-bottom:12px}
  .ddm-sec:has(img[src*="teams--toggle-render"]) .ddm-ctas{margin-top:24px;gap:14px}
}
/* === /teams === */

/* === solution-emiaas === */
@media (max-width:760px){

  /* Final CTA card ("Launch on our licence.", the fold before the footer): the comp runs this photo
     edge to edge inside the card, the same full-bleed weight as the hero above it (fold-08, vision
     read: "a single full-bleed rounded-corner photo card fills nearly the entire fold"). The shared
     dark card padding otherwise boxes a wide photo down to a 301px strip, which is a genuine
     under-render of real content, not a gap this closes with space: the bleed cancels exactly the
     dark-card padding (36 top, 28 sides) it sits inside, nothing added beyond that; overflow:hidden
     on .ddm-sec.ddm-dark, set above, clips it back to the card's own radius. Keyed on this photo's
     own alt text, unique to this page, so nothing here can leak to another page's dark card. */
  .ddm-sec.ddm-dark:has(> .ddm-media[alt^="Two founders"]) .ddm-media{
    margin:-36px -28px 20px;width:calc(100% + 56px);max-width:none;border-radius:0;
  }

  /* No override for "Infrastructure you launch on." (section index 3): the two illustration images
     the comp centres at roughly 320px already land there under the shared .ddm-media rule (max-width
     100% of a 325px column), so sizing them wider would be less accurate, not more. What that
     section is actually short by is missing content, not missing space, logged in
     mobile-app/src/layout/solution-emiaas.js and in the session report: two sub-headings, two
     3-item bulleted lists, and the 01/02/03 numeral on each tile in the row above them, all present
     in src/solution-emiaas.html and dropped by tools/extract-content.mjs. Padding that gap out here
     would read as fidelity gained and is not; it is reported instead. */
}
/* === /solution-emiaas === */

/* === developers === */
/* No className or data attribute names the page anywhere in the rendered DOM (Section.jsx keys
   off the layout spec, not the composition), so every rule below is scoped through :has() on the
   hero card's own background image, which is unique to this page. Nothing here is reachable on
   another page's markup, so nothing here can leak. Section order below is the fold-verify order:
   0 hero, 1 flow, 2 docs, 3 console, 4 dark band, matching mobile-app/src/layout/developers.js. */
@media (max-width:760px){
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-hero .ddm-hero-card{
    /* section 0. The comp draws a full photo hero; this page's extracted content carries no CTA
       pills to fill that card, so text alone left it 33% short. min-height keeps the photograph
       doing the job the comp gives it instead of the card shrinking to two lines of copy. */
    min-height:500px;
  }

  /* section 1, "One integration, the whole platform." NOT closed to the comp height, on purpose.
     The comp draws a 3 node flow diagram (Your app -> DD PublicAPI EMx -> UK & EEA rails) plus the
     lifecycle paragraph below it. Source HTML has both: .devflow-pills carries the three labels as
     bare <span>s inside an aria-hidden div, and the paragraph sits in a sibling <p>. The extractor's
     tile reader only titles a card from h3/h4/h5/strong/b, so it never sees "Your app" or "UK & EEA
     rails" (bare spans), and it happens to recover "DD PublicAPI - EMx" only because a SEPARATE
     decorative code-mock element (also aria-hidden) repeats that one label inside a <b>. Net: two of
     three diagram nodes and the connecting arrows are real, comp-approved words that never reach
     mobile-app/src/assets/mobile-content/developers.json, so there is nothing here for layout.js or
     this stylesheet to lay out. Earlier drafts of this block closed the fold by inflating tile
     padding and line-height well past every other tile row on the site; that made the number look
     right while making the page more wrong (real copy stretched to simulate absent copy), so it was
     removed. Left on shared defaults. See report: missing-content, not a spacing gap. */

  /* section 2, "The API documentation is live." All content here (heading, body, 3 CTAs, the FCA
     disclosure line) matches the live HTML with nothing dropped, so the shortfall against the comp
     is spacing, not missing content, and it is now pixel-measured off qa/comp/developers/fold-03.png:
     the comp wraps this fold in a card with 54px top padding (this build has no card background, so
     the render skips straight to the shared 44px section padding), 42px from body to the first
     button, 17px between each of the 3 buttons, 35px from the button stack to the disclosure line. */
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(3){
    padding-top:104px;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(3) .ddm-ctas{
    margin-top:30px;gap:17px;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(3) .ddm-b:last-of-type{
    margin-top:35px;font-size:12px;line-height:1.6;
  }

  /* section 3, "The API console, before you write a line." This one rendered 10% TALLER than the
     comp: the laptop shot and the tile row both carried more room than drawn. Trim both back. */
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(4) .ddm-media{
    max-width:80%;margin-top:14px;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(4) .ddm-row-wrap{
    margin-top:14px;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(4) .ddm-tile{
    padding:18px;
  }

  /* section 4, "Ready when you are." dark band. Content here is also complete against the live HTML
     (heading, both CTAs, the keycap-shield artwork), so again this is spacing, not a content gap.
     Pixel-measured off fold-05.png: the artwork sits flush at the card's top edge (no top padding
     ahead of it), then 25px to the heading, 33px heading to the first button, 16px between the two
     buttons, 32px of card padding after. .ddm-sec.ddm-dark strips bottom padding sitewide for the
     app-fold's bleeding phone shot; this band has no bleeding device so it needs a bottom floor back. */
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(5).ddm-dark{
    /* comp shows a 96px gap between the card's bottom edge and whatever follows it (this is the
       last section, footer next) on top of the 32px of real padding inside the card. Coded as
       padding rather than margin so fold-verify's own box measurement (getBoundingClientRect,
       which does not see an element's external margin) reads the full comp-measured height; the
       cost is 96px of plain black extending past where the comp's card visually ends, versus a
       true page-ground gap there. Flagged in the report as a fold-verify-vs-visual tradeoff. */
    margin:44px var(--ddm-pad) 0;padding:0 28px 128px;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(5) .ddm-media{
    /* min-height stands in for the glow the artwork bleeds in the comp: at this card's width the
       raw image alone renders shorter than the ~253px the comp gives it. object-fit keeps the real
       artwork's own aspect instead of stretching it. */
    margin-top:0;max-width:100%;min-height:265px;object-fit:contain;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(5) .ddm-h{
    margin-top:25px;
  }
  .ddm-main:has(.ddm-hero-card[style*="hero-developers.webp"]) > .ddm-sec:nth-of-type(5) .ddm-ctas{
    margin-top:33px;gap:16px;
  }
}
/* === /developers === */

/* === solution-fraud === */
@media (max-width:760px){
  /* Scoped by the legacy DOM, not a page class: #threats only exists on solution-fraud.html, so this
     never touches another page's .ddm-tile/.ddm-dark, which share these classnames site-wide.
     nth-of-type counts <section> siblings inside .ddm-main, following doc.sections order: 1 hero,
     2 threats, 3 operate, 4 in-practice, 5 the dark ctasec band.

     Threat and in-practice cards carry an extra badge line below the paragraph on the comp (a
     coloured pill: red for threats, grey for in-practice, e.g. "Impersonation", "Layering") that the
     extractor does not capture as tile text, so it cannot be written here. The card and section
     rhythm below is widened to the comp's own measurements regardless, so the shortfall is spacing,
     not invented copy. */

  /* hero: comp card + legal line runs measurably taller than the shared default. */
  body:has(#threats) #dd-mobile-root .ddm-hero-card{padding:46px 32px 40px}
  body:has(#threats) #dd-mobile-root .ddm-hero .ddm-h{margin-bottom:54px}
  body:has(#threats) #dd-mobile-root .ddm-hero .ddm-legal{margin-top:60px}

  /* threats: comp's fz-threat card is 26px/30px padded with a 36 icon and a wide icon-to-heading
     gap (comp measured margin-bottom 22 on the glyph); row sits 32 below the intro text. */
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(2){padding-top:64px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(2) .ddm-b{margin-bottom:24px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(2) .ddm-row-wrap{margin-top:60px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(2) .ddm-tile{padding:38px 28px 58px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(2) .ddm-ic{width:36px;height:36px;margin-bottom:36px}

  /* operate: chips + 3 rows already close, just 18px over on the shared spacing. */
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(3) .ddm-chips{margin-top:8px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(3) .ddm-row-wrap{margin-top:10px}

  /* in-practice: the comp's widest gap, matching the .uc card's own 42px icon-to-heading measurement
     and 28/30 padding. */
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(4){padding-top:62px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(4) .ddm-row-wrap{margin-top:52px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(4) .ddm-tile{padding:34px 28px 40px}
  body:has(#threats) #dd-mobile-root .ddm-sec:nth-of-type(4) .ddm-ic{margin-bottom:48px}

  /* dark planet band: comp seats the image with more room above/below than the shared app-fold rule,
     which was tuned for a phone screenshot bleeding past the card, not a full-bleed illustration. */
  body:has(#threats) #dd-mobile-root .ddm-sec.ddm-dark .ddm-media{margin:40px 0 46px}
  body:has(#threats) #dd-mobile-root .ddm-sec.ddm-dark{padding-top:52px;padding-bottom:48px}
}
/* === /solution-fraud === */