/* ============================================================================
   onsite-landing.css
   ----------------------------------------------------------------------------
   The ONLY stylesheet in this folder that is not a copy of one from
   claude-grouped-website. Everything else in styles/ is the grouped.org.uk
   design system, copied verbatim so the two sites stay visually identical.

   ⚠ WHY THIS LOADS AFTER modular.css, WHEN THE DESIGN SYSTEM SAYS modular.css
     MUST BE LAST: modular.css has to beat the older background tints declared
     in product-v3.css and onsite-v2.css. This file declares NO section
     background, NO page background, and touches none of modular.css's
     selectors, so it cannot undo that. It only adds two components the main
     site has no equivalent of.

   ⚠ KEEP IT THAT WAY. If you ever need a rule here that sets a section
     background, put it in modular.css instead, or the "every section is white"
     rule silently breaks on this page only.

   The two components, and why the main site doesn't have them:
     .os-proof   the three claims under the hero (4 MIS systems / one price /
                 bilingual). grouped.org.uk sells the whole platform; this site
                 sells OnSite alone, so it leads with OnSite's own numbers.
     .os-accred  Everything ICT, Government Commercial Agency and Cyber Essentials
                 Plus — the same three grouped.org.uk's hero carries (it runs them
                 in a different order; nothing turns on that). They are
                 procurement signals that matter on a
                 landing page a school reaches from an advert, where there is no
                 "About us" to go and check. Do not drop them without asking
                 Rebecca.
   ========================================================================== */

/* --- the proof band ------------------------------------------------------ */

.hv2 .os-proof {
  padding-top: clamp(40px, 5vw, 64px);
  padding-bottom: clamp(40px, 5vw, 64px);
}

/* .proof / .proofrow themselves are the design system's own components, styled
   in home-v2.css. modular.css zeroes .proofrow's negative top margin so it sits
   inside this band rather than hanging up over the hero, which is correct under
   modular bands: there is no flat section edge left to straddle. */

/* --- the accreditation strip --------------------------------------------- */

.hv2 .os-accred {
  margin-top: clamp(32px, 4vw, 48px);
  padding-top: clamp(24px, 3vw, 32px);
  border-top: 1px solid #E6ECF4;
}

/* Eyebrow, not a navy pill. The design system's .eyebrow is a filled navy pill
   and the rule is one per section; this strip sits inside the proof band and a
   second pill there would compete with the three claims above it. Uppercase is
   sanctioned for eyebrows, and 12px is the site-wide floor. */
.hv2 .os-accred__label {
  margin: 0 0 clamp(16px, 2vw, 22px);
  text-align: center;
  font-size: 12px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #4A5876;
}

/* One quiet line: the label and the three marks, centred, on a single row.
   History, so nobody reinstates a rejected version (all 06/10/2026):
     · white tiles with names underneath, matching the feature tiles. Rejected:
       it put two rows of near-identical boxes a short scroll apart, with the
       LESS important row on top.
     · the same without boxes, names kept. Rejected in favour of this.
   What survived is the quietest treatment. These are a trust signal a reader
   glances at, not something to stop and read, so they sit below the three
   claims above them rather than competing. */
.hv2 .os-accred {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 16px clamp(28px, 4vw, 52px);
}

.hv2 .os-accred__label {
  margin: 0;
  text-align: center;
  font-size: 12px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #4A5876;
}

/* Fixed-height well, and the logos are matched on HEIGHT, never width: the
   three certificate files are different shapes and two carry their own white
   box baked in, so sizing by width left the G-Cloud mark a third larger than
   the other two and the row read as lopsided.
   Rebecca, 06/10/2026: "make the logos bigger". Was 34px; now up to 54px, so
   roughly half as tall again. They are the largest thing in this block, which
   is the intent: with the names gone the marks have to carry it alone. */
.hv2 .os-accred__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: clamp(42px, 4.6vw, 54px);
  border-radius: 10px;
  transition: opacity 200ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.hv2 .os-accred__logo img {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 100%;
}

.hv2 .os-accred__logo:hover { opacity: 0.72; }

.hv2 .os-accred__logo:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(47, 183, 241, 0.45);
}

@media (prefers-reduced-motion: reduce) {
  .hv2 .os-accred__logo { transition: none; }
}

/* Below tablet the label takes its own line above the three marks, rather than
   wrapping to sit alone and off-centre at the end of the row. */
@media (max-width: 620px) {
  .hv2 .os-accred__label { flex: 0 0 100%; }
  .hv2 .os-accred__logo { height: 40px; }
}

/* --- MIS section as a grey module ---------------------------------------- */
/* onsite-v2.css gives .os-mis clamp(48px,5.4vw,84px) top and clamp(80px,9vw,140px)
   bottom. That asymmetry is invisible on grouped.org.uk, where this section is
   white and the extra bottom padding just reads as the gap before the next
   band. Inside a grey card it is not invisible: it puts up to 56px more grey
   below the text than above it, and the panel looks like it has slipped.
   Balanced here, and only while the section is actually a module. */
.hv2 .os-mis.band--module {
  padding-top: clamp(48px, 5.4vw, 84px);
  padding-bottom: clamp(48px, 5.4vw, 84px);
}

/* --- benefit grids: columns that suit the number of tiles ------------------ */
/* The design system ships this grid at 4 across, which is right for a 4-tile
   grid and leaves a widowed row otherwise.
   ⚠ THIS USED TO BE A BLANKET `repeat(3, 1fr)`, added 06/10/2026 so the
   homepage's SIX tiles read as 2 rows of 3. It was applied to every grid on
   every page, so the two FOUR-tile grids (partners, launch campaign) fell
   3 + 1, which looks like a mistake. Count-aware now:
     3 tiles -> 3 across (one clean row)
     6 tiles -> 3 across (two clean rows)
     anything else -> the system's 4, untouched
   ⚠ MIN-WIDTH, not a bare rule. product-v3.css already drops this grid to two
   columns under 1020px and one under 600px, and this sheet loads after it, so
   a bare rule would beat both and force three cramped columns onto a phone. */
@media (min-width: 1021px) {
  .hv2 .pv3-ben__grid:has(> .pv3-ben:nth-child(3)):not(:has(> .pv3-ben:nth-child(4))),
  .hv2 .pv3-ben__grid:has(> .pv3-ben:nth-child(6)):not(:has(> .pv3-ben:nth-child(7))) {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* The icon tints cycle every FOUR tiles (home-v2.css ~4050): tile 1 keeps the
   base colour, then green, violet, amber. With six tiles the fifth falls back
   to the base, so tiles 1 and 5 matched, and in a 3-wide grid they sit directly
   above one another in column 1, which reads as a mistake.
   The design system already solved this for its own six-tile grids
   (.ph-ben__grid, .ml-caps) with a sky fifth. Same values, applied here. */
.hv2 .pv3-ben__grid > .pv3-ben:nth-child(4n + 5) .pv3-ben__ico {
  background: #D9F4FF;
  color: #1B367E;
}

/* --- bullet list and footnote inside the dark .pp-band ---------------------- */
/* Used on partners.html ("Want to become a partner?"). The design system's
   .pp-band ships a heading and a paragraph but no list, and this band needed
   the four partner benefits as discrete points rather than one run-on sentence.
   ⚠ The band background is --ge-navy, so everything here is light-on-dark. Do
   not reuse these two classes on a white band: the text would vanish. */

.hv2 .pp-band__points {
  list-style: none;
  margin: 18px 0 26px;
  padding: 0;
  display: grid;
  gap: 12px;
}

/* Tick discs follow the design system's rule for a dark surface: the normal
   navy-disc-with-white-glyph inverts to a white disc with a navy glyph. */
.hv2 .pp-band__points li {
  position: relative;
  padding-left: 34px;
  font-size: 16px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
}

.hv2 .pp-band__points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F1438' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E")
    center / 13px 13px no-repeat;
}

.hv2 .pp-band__alt {
  margin: 18px 0 0;
  font-size: 15px;
  color: rgba(255, 255, 255, 0.72);
}

.hv2 .pp-band__alt a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.hv2 .pp-band__alt a:hover { color: rgba(255, 255, 255, 0.82); }

/* ===========================================================================
   MARTYN'S LAW PAGE
   Components the design system has no equivalent of. All white-band safe:
   nothing here sets a section background, per the rule at the top of this file.
   =========================================================================== */

/* --- countdown to enforcement -------------------------------------------- */
/* Filled by scripts/countdown.js via [data-tminus] and [data-cd]. The numbers
   are display figures, so they keep weight 700 under the design system's rule
   that big stats stay bold while headings drop to 600. */

.hv2 .mlcd {
  margin: clamp(26px, 3vw, 36px) 0 clamp(28px, 3.4vw, 40px);
}

.hv2 .mlcd__eyebrow {
  display: block;
  margin-bottom: 12px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #4A5876;
}

.hv2 .mlcd__units { display: flex; gap: clamp(14px, 2vw, 22px); }

.hv2 .mlcd__unit {
  min-width: 108px;
  padding: 16px 20px;
  border-radius: 16px;
  background: #F3F7FA;
  text-align: center;
}

.hv2 .mlcd__num {
  display: block;
  font-size: clamp(30px, 3.4vw, 42px);
  font-weight: 700;
  line-height: 1.05;
  color: #0F1438;
  font-variant-numeric: tabular-nums;
  /* tabular-nums stops the box resizing as the digits tick over. */
}

.hv2 .mlcd__lbl {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  color: #4A5876;
}

/* --- pull quote ----------------------------------------------------------- */

.hv2 .ml-quote {
  margin: 22px 0 0;
  padding: 18px 0 18px 22px;
  border-left: 3px solid #D9F4FF;
}

.hv2 .ml-quote p {
  margin: 0 0 10px;
  font-size: 17px;
  line-height: 1.6;
  color: #0F1438;
}

.hv2 .ml-quote footer { font-size: 14px; color: #4A5876; }
.hv2 .ml-quote cite { font-style: normal; font-weight: 600; color: #0F1438; }

/* --- key facts list ------------------------------------------------------- */

.hv2 .ml-facts {
  padding: clamp(24px, 2.6vw, 32px);
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(15, 20, 56, 0.08);
}

.hv2 .ml-facts__title { margin: 0 0 16px; font-size: 19px; }

.hv2 .ml-facts__list { margin: 0; display: grid; gap: 14px; }

.hv2 .ml-facts__list > div {
  display: grid;
  gap: 2px;
  padding-bottom: 14px;
  border-bottom: 1px solid #EEF2F7;
}
.hv2 .ml-facts__list > div:last-child { padding-bottom: 0; border-bottom: 0; }

.hv2 .ml-facts__list dt {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #4A5876;
}

.hv2 .ml-facts__list dd {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.45;
  color: #0F1438;
}

/* --- sources -------------------------------------------------------------- */

.hv2 .ml-sources {
  padding-top: clamp(40px, 5vw, 64px);
  padding-bottom: clamp(40px, 5vw, 64px);
}

.hv2 .ml-sources__title { font-size: 22px; margin: 0 0 18px; }

.hv2 .ml-sources__list { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 12px; }

.hv2 .ml-sources__list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 12px;
  border-bottom: 1px solid #EEF2F7;
}

.hv2 .ml-sources__list a { color: #1B367E; font-size: 16px; }
.hv2 .ml-sources__list a:hover { color: #0F1438; }
.hv2 .ml-sources__list span { font-size: 13px; color: #4A5876; }

.hv2 .ml-sources__note { margin: 0; font-size: 14px; line-height: 1.6; color: #4A5876; max-width: 62ch; }

@media (max-width: 620px) {
  .hv2 .mlcd__units { flex-wrap: wrap; }
  .hv2 .mlcd__unit { flex: 1 1 calc(50% - 11px); min-width: 0; }
}

/* --- countdown on a dark band --------------------------------------------- */
/* The launch campaign page puts the Martyn's Law countdown inside .pp-band,
   which is navy. The light version above would be invisible there. */

.hv2 .mlcd--dark .mlcd__eyebrow { color: rgba(255, 255, 255, 0.62); }
.hv2 .mlcd--dark .mlcd__unit { background: rgba(255, 255, 255, 0.1); }
.hv2 .mlcd--dark .mlcd__num { color: #fff; }
.hv2 .mlcd--dark .mlcd__lbl { color: rgba(255, 255, 255, 0.66); }

/* --- small page-specific bits --------------------------------------------- */

/* become-a-partner hero: the reassurance line under the buttons.
   ⚠ It sits on the VIOLET hero, so it is light-on-dark. It was slate #4A5876,
   which was readable while that hero was white and became invisible the day
   every hero went violet (Rebecca, 09/10/2026: "cant read buttons and text").
   It is used in exactly one place, so the colour is simply changed rather than
   given a modifier. */
.hv2 .bp-hero__note {
  margin: 18px 0 0;
  font-size: 14.5px;
  color: rgba(255, 255, 255, 0.78);
}

/* partners directory: a card whose logo is a bitmap rather than initials.
   The modifier existed in the markup but never had a rule, so the image sat at
   its natural size. Bounded here so a large PNG cannot blow out the card. */
.hv2 .partner-card__logo--img img {
  max-width: 100%;
  max-height: 56px;
  width: auto;
  object-fit: contain;
}

/* --- the proof numbers inside a testimonial card --------------------------- */
/* Rebecca, 08/10/2026: these belong under the Cwmbran byline, small, rather
   than in a row below both testimonials. They are that school's own figures and
   the quote above them names the 1,200, so attributing them to the pair was
   misleading as well as loud.
   The numbers keep weight 700: the design system drops HEADINGS to 600 but big
   display figures stay bold, and these are figures. */

.hv2 .tcar__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px clamp(18px, 2.4vw, 28px);
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid #EEF2F7;
  font-size: 13.5px;
  line-height: 1.45;
  color: #4A5876;
}

.hv2 .tcar__stats strong {
  font-weight: 700;
  color: #0F1438;
  /* tabular-nums so the box does not twitch while the count-up runs */
  font-variant-numeric: tabular-nums;
}

@media (max-width: 520px) {
  .hv2 .tcar__stats { flex-direction: column; gap: 4px; }
}


/* ===========================================================================
   EVERY HERO LEADS WITH ONSITE VIOLET
   Rebecca, 08/10/2026: "i want all onsite heros to be violet across all the
   site". This is also what the design system asks for: a product's own pages
   lead with that product's identity colour, and GroupEd blue is the
   cross-product palette.

   ⚠ --pp-ink, NEVER a hard-coded #614DBA. body.pp--onsite defines it, it is
   exactly what the homepage .pv3g__frame reads, and it means one edit moves
   every hero if the OnSite colour is ever re-specified.

   The four hero types on this site, and where each is used:
     .pv3g__frame     homepage, launch campaign     already violet, untouched
     .statement--hero book a demo, Martyn's Law, become a partner
     .pn-hero__grid   partners
     .auth-visual     start a free trial
   =========================================================================== */

/* --- .statement--hero ------------------------------------------------------ */
/* modular.css ships this pale (--ge-bg-light) with dark text, and separately
   paints the demo one GroupEd blue. Both are overridden here for ALL of them,
   so a new page using this hero is violet without a further edit.
   Same specificity as the rules replaced; wins by this sheet loading later. */
body.hv2 main > section.statement--hero,
body.hv2 main > section.statement--hero.dm-hero {
  background: var(--pp-ink, #614DBA);
}

body.hv2 .statement--hero .statement__line { color: #fff; }
body.hv2 .statement--hero .statement__sub { color: rgba(255, 255, 255, 0.82); }
body.hv2 .statement--hero .statement__when,
body.hv2 .statement--hero .statement__note { color: rgba(255, 255, 255, 0.74); }

/* ⚠ NO PILL ON ANY HERO HEADLINE. Rebecca, 09/10/2026: "there shouldnt be any
   title pills in heros".

   The design system puts a highlight pill behind a marked phrase in a hero
   headline — pale sky #D9F4FF with blue text in modular.css, which this file
   had been overriding to white-on-violet (08/10/2026, "the hero pill in the h1
   cant be blue - choose a white"). Both are now off: the marked phrase renders
   as ordinary headline text.

   ⚠ NEUTRALISED, NOT DELETED, and the long selector list is why. modular.css
   styles the pill as `body.hv2 .statement--hero.dm-hero .statement__line .mark`
   — two classes on the hero — so a plain `.statement--hero` selector loses on
   specificity however late this file loads. Simply removing the rules here
   would bring modular.css's pale-sky pill straight back on those heroes. Every
   variant therefore has to be named and switched off explicitly.

   ⚠ The <span class="mark"> stays in the markup on all four pages. It records
   which phrase is the emphasis, costs nothing while unstyled, and is how the
   design system treats its own retired devices (see .dim in product-v3.css).
   Pills OUTSIDE heroes are untouched — none of these selectors reaches them. */
body.hv2 .statement--hero .statement__line .mark,
body.hv2 .statement--hero.dm-hero .statement__line .mark,
body.hv2 .statement--hero.fc-hero .statement__line .mark,
body.hv2 .statement--hero.ml-hero .statement__line .mark,
body.hv2 .statement--hero.bp-hero .statement__line .mark,
body.hv2 .pn-hero .pn-hero__title .mark,
/* ⚠ :not(.home) IS LOAD-BEARING on these three, not decoration. modular.css's
   own "hero pills go white off the home page" rule is written as
   `body.hv2:not(.home) .pv3g h1 .mark` — four classes. A plain
   `body.hv2 .pv3g h1 .mark` is three and LOSES, however late this file loads:
   padding and radius came off, the white background and blue text stayed, and
   Martyn's Law kept a pill while the other three lost theirs. Matching their
   selector exactly makes it a cascade-order win instead of a specificity one.
   .hero2 is listed for the same reason even though no page here uses it yet. */
body.hv2:not(.home) .pv3g h1 .mark,
body.hv2:not(.home) .hero2 h1 .mark,
body.hv2:not(.home) .hero2__copy h1 .mark {
  display: inline;
  background: none;
  color: inherit;
  border-radius: 0;
  padding: 0;
  margin-block: 0;
  line-height: inherit;
}

/* White pill, navy text, navy arrow disc: the site's treatment for a button on
   photography or any dark surface. */
body.hv2 .statement--hero .statement__cta,
body.hv2 .statement--hero.dm-hero .statement__cta {
  background: #fff;
  border-color: #fff;
  color: var(--ge-navy, #0F1438);
}
body.hv2 .statement--hero .statement__cta:hover,
body.hv2 .statement--hero.dm-hero .statement__cta:hover {
  background: #EDE9FB;
  border-color: #EDE9FB;
  color: var(--ge-navy, #0F1438);
}
body.hv2 .statement--hero .statement__cta .btn__arrow {
  background: var(--ge-navy, #0F1438);
  color: #fff;
}

/* ⚠ .eyebrow--violet IS VIOLET ON VIOLET once the hero turns. Martyn's Law,
   become a partner and partners all use it, so it has to invert on a hero. */
body.hv2 .statement--hero .eyebrow--violet,
body.hv2 .pn-hero .eyebrow--violet {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}

/* The secondary hero button, likewise. */
body.hv2 .statement--hero .st-hero__ghost {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.5);
  color: #fff;
}
body.hv2 .statement--hero .st-hero__ghost:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: #fff;
  color: #fff;
}

/* --- .pn-hero (partners) --------------------------------------------------- */
/* partners.css hard-codes #4A3995, a darker violet that reads as a different
   colour beside the homepage hero. */
body.hv2 .pn-hero__grid { background: var(--pp-ink, #614DBA); }

/* --- buttons inside the dark .pp-band -------------------------------------- */
/* ⚠ THE DESIGN SYSTEM PUTS NO BUTTONS IN .pp-band, so product-page.css styles
   none: it sets `.pp-band .btn { flex: none }` and nothing else. The buttons
   added here (partners, become a partner, launch campaign) therefore inherited
   the default blue-on-transparent and were close to invisible on the navy card.
   Same white-pill treatment as a hero button on a dark surface. */
body.hv2 .pp-band .btn {
  background: #fff;
  border-color: #fff;
  color: var(--ge-navy, #0F1438);
}
body.hv2 .pp-band .btn:hover {
  background: #EDE9FB;
  border-color: #EDE9FB;
  color: var(--ge-navy, #0F1438);
}
body.hv2 .pp-band .btn .btn__arrow {
  background: var(--ge-navy, #0F1438);
  color: #fff;
}

/* --- a dark card as the LAST section before the contact band --------------- */
/* ⚠ DO NOT RESTORE THE STRADDLE HERE. The footer's contact card normally rises
   with a negative margin into the section above, which reads beautifully when
   that section is WHITE: a pale card lifting out of the navy footer.
   On partners.html the last section is .pp-band, which is navy, and the FOOTER
   is navy, and the card is exactly the same width as the band. So the straddle
   produced navy / pale / navy in three flush stacked blocks of identical width,
   with no gap anywhere and nothing reading as "in front of" anything else.
   Rebecca, 08/10/2026: "theres still no gap between the sections".
   On a dark last section the card therefore sits BELOW it, on the site's normal
   24px inter-band gap, and the band keeps its ordinary padding. */
body.hv2:has(main > section:last-child.pp-band) .cb--footer .cb__card {
  margin-top: 24px;
}

body.hv2:has(.cb--footer) main > section:last-child.pp-band {
  padding-bottom: clamp(56px, 6vw, 88px);
}

/* --- .auth-visual (start a free trial) ------------------------------------- */
/* create-account.css hard-codes #5B50A7 here, which is a different violet from
   the OnSite one: close enough to look like a mistake rather than a choice when
   the two pages sit side by side. Same token as every other hero. */
body.hv2 .auth-visual { background: var(--pp-ink, #614DBA); }

/* --- one hero title size across the whole site ----------------------------- */
/* Rebecca asked whether hero titles matched, 08/10/2026. They did not: three
   hero components, three different scales, which differ at every width rather
   than just one.
     .pv3g h1          clamp(36px, 4.4vw, 62px)   homepage, launch campaign
     .statement__line  clamp(32px, 5.2vw, 84px)   demo, Martyn's Law, become a partner
     .pn-hero__title   clamp(30px, 4.4vw, 48px)   partners
   At 1440px that rendered 62 / 75 / 48. All three now use the homepage's
   clamp, so they track together as the window resizes rather than only
   matching at one width.

   ⚠ Scoped to .statement--hero, NOT bare .statement__line: the same class is
   used on statement BANDS mid-page, which are meant to be a different size.
   ⚠ The two form pages (start a free trial, partner application) are NOT
   included. Their h1 is a form-card title at 33px, not a hero headline, and
   making it hero-sized would overwhelm the form it introduces. */
.hv2 .statement--hero .statement__line,
.hv2 .pn-hero__title {
  font-size: clamp(36px, 4.4vw, 62px);
}

/* --- the contact card must paint ABOVE the section it straddles into ------- */
/* The footer's contact card rises with a negative margin into whatever section
   is last. It ships position:static with no z-index, which is fine against an
   ordinary section, because a later sibling paints on top.
   ⚠ IT IS NOT FINE AGAINST A POSITIONED SECTION. A positioned element paints
   above a static one whatever the DOM order, so .pp-band (position:relative)
   painted straight over the card and swallowed its heading: the words were in
   the page, just buried. Removing the section's --sz z-index was NOT enough on
   its own, which is the part worth remembering.
   Giving the card its own stacking position fixes it for every section type,
   positioned or not. */
body.hv2 .cb--footer {
  position: relative;
  z-index: 3;
}

/* --- the demo page's bento, now photo-less --------------------------------- */
/* Rebecca, 09/10/2026: "on the book a demo page you can remove the photo".
   demo.css lays that grid out as four columns with the two text tiles in 1-3
   and the photo (.dm-bento__d) spanning 3-5 across both rows. Take the photo
   out of the markup and the tiles keep their half-width placement, leaving the
   right half of the band empty.

   ⚠ KEYED ON :has(), NOT ON THE PAGE. The rule asks "is the photo actually
   there?" rather than "is this book-a-demo?", so dropping the <img> back into
   the markup restores the two-up layout on its own and nothing here has to
   change. Same approach as the count-aware benefit grid further up this file.

   The tiles stay STACKED rather than going side by side, which is deliberate:
   Rebecca asked for exactly that on 06/08/2026 ("i think the boxes with text
   need to be on top of each other") and losing the photo is not a reason to
   undo it.

   (This replaces the 08/10/2026 "zoomed out" rule for the same photo, which
   became dead the moment the <img> came out.) */
.hv2 .dm-bento:not(:has(.dm-bento__d)) {
  grid-template-rows: auto auto;
}
.hv2 .dm-bento:not(:has(.dm-bento__d)) .dm-bento__a,
.hv2 .dm-bento:not(:has(.dm-bento__d)) .dm-bento__b {
  grid-column: 1 / 5;
}
/* ⚠ AND CAP THE MEASURE. At half width those paragraphs were ~55 characters
   a line; full width they run to about 150, which is past the point where the
   eye loses its place returning to the left margin. The tile keeps its new
   width — only the text stops short, which is what .pv3g__lede's own 44ch cap
   does on the hero. */
.hv2 .dm-bento:not(:has(.dm-bento__d)) .dm-tile p { max-width: 72ch; }

/* --- "Four ways your school will use OnSite": real photos, not screenshots --- */
/* Rebecca, 09/10/2026: "I want to refresh the photos used in the Four ways your
   school will use OnSite. I want to use real photos".
   The tile was built on 05/08/2026 as One's "Everything in One" treatment — a
   violet panel with a handset running off the bottom edge — and the four school
   photos that used to sit here came off as a consequence. This puts photography
   back, and keeps everything else about the tile: the violet panel, its radius,
   its 5:4 ratio and the sitewide chunky white frame around whatever it holds.
   Two of the four photos have OnSite on screen in them (the reception kiosk, the
   roll-call phone), so the product is still shown, in context rather than
   floating.
   ⚠ OPT-IN BY MODIFIER. Everything hangs off .os-way__media--photo, so the
   handset treatment is untouched and still available: delete the modifier and
   the --phone frame class comes back exactly as it was. */
.os-mods .os-way__media--photo {
  /* the handset deliberately overflowed the bottom, so the tile had
     padding-bottom:0. Nothing overflows now, so the padding is even. */
  align-items: stretch;
  padding: clamp(16px, 1.7vw, 28px);
}
.os-mods .os-way__media--photo .pv3-acc__frames {
  /* fill the tile rather than imposing a second ratio inside the 5:4 one —
     the four photos are 4:3 and 16:9, and cover crops them to the tile. */
  aspect-ratio: auto;
  flex: 1 1 auto;
  min-width: 0;
  border-radius: clamp(14px, 1.4vw, 20px);
}
.os-mods .os-way__media--photo .pv3-acc__shot {
  /* reset two phone-only rules: the screen's deep corner radius, and the
     top-anchored crop that kept a screenshot's status bar in view. */
  border-radius: 0;
  object-position: 50% 50%;
}
/* per-photo framing — each one has its subject somewhere different, and a
   centred crop loses it. Matched to the tab order: reception, staff,
   evacuation, lockdown. */
.os-mods .os-way__media--photo:nth-child(1) .pv3-acc__shot { object-position: 60% 50%; }
.os-mods .os-way__media--photo:nth-child(2) .pv3-acc__shot { object-position: 55% 50%; }
.os-mods .os-way__media--photo:nth-child(3) .pv3-acc__shot { object-position: 50% 55%; }
.os-mods .os-way__media--photo:nth-child(4) .pv3-acc__shot { object-position: 60% 50%; }  /* 16/10/2026: the lockdown tile is now a still lifted from the OnSite film — a pupil at an iMac filled with the red lockdown screen. The iMac sits right of centre and its far edge is ~87% across, so the crop is pushed right to keep the whole machine; what goes is the back of the pupil's head, which is not the subject. (Was 0% for the previous photo, whose board sat hard against the left edge.) */

/* --- hero watermark on the Become a partner hero -------------------------- */
/* Rebecca, 09/10/2026: "can we add a watermark icon to the hero".
   Martyn's Law and Become a partner were the only heroes on the site without
   one — both have a wide empty right-hand side where every other hero carries
   the GroupEd hexagon bleeding off the edge.
   ⚠ Martyn's Law has since moved to the home page's .pv3g hero (see the block
   at the foot of this file), which brings its own .pv3g__wm. These rules now
   serve Become a partner alone — the .ml-hero selectors are kept because that
   class is still on nothing, and removing them is a separate tidy-up.

   ⚠ THE NUMBERS BELOW ARE COPIED, NOT INVENTED. The master is the shared
   hero-mark rule in modular.css (search for `.dm-hero__mark`), which lists
   seven page-specific class names and gives them ONE geometry on purpose —
   there used to be six different treatments at three different opacities, and
   that rule is what ended it. If the site-wide mark ever changes, change it
   there and bring these into line; do not let the two drift.
   0.07 is the white-mark-on-a-dark-card value. The 0.05 exception in that rule
   is only for the two PALE heroes (Launch Deal, Book a Demo), where a sky-blue
   mark at 7% reads as a blue shape rather than a ghost. These two are violet
   with a white mark, so they take 0.07 like the rest.

   ⚠ FOUR RULES, NOT ONE. The shared rule sets only top/right/width/opacity and
   assumes the mark is already positioned with a sized <img> inside. Book a Demo
   hit exactly this: without the positioning the <span> stays inline, `width` is
   ignored on an inline box and the mark renders at the image's intrinsic height
   across the full container. The hero needs position:relative to anchor it, and
   the .container needs its own stacking context or the mark paints over the
   headline. */
body.hv2 .ml-hero,
body.hv2 .bp-hero { position: relative; }

body.hv2 .ml-hero > .container,
body.hv2 .bp-hero > .container { position: relative; z-index: 1; }

body.hv2 .os-hero__mark {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  line-height: 0;
  top: clamp(-40px, 2vw, 30px);
  bottom: auto;
  right: clamp(-240px, -15vw, -120px);
  width: clamp(420px, 60vw, 960px);
  opacity: 0.07;
}
body.hv2 .os-hero__mark img { width: 100%; height: auto; display: block; }

@media (max-width: 900px) {
  body.hv2 .os-hero__mark {
    right: clamp(-200px, -16vw, -100px);
    width: clamp(400px, 66vw, 700px);
  }
}


/* --- Martyn's Law: the home page's hero, flipped, with a photo carousel ---- */
/* Rebecca, 09/10/2026: "can we give the martyns law the same hero styling as
   the homepage" and then "can we make the photo on the left a carousel of the
   4 photos we use on the home page".

   The page now uses .pv3g — the same component index.html's hero is built from
   — so the card, the type scale, the eyebrow pill, the button treatment, the
   watermark and the photo's position on the right all come free and cannot
   drift from the home page. Everything below is only what differs.

   ⚠ THE PHOTO STAYS ON THE RIGHT, which is where .pv3g puts it and where the
   home page has it. It was briefly flipped to the left on 09/10/2026 and put
   back the same day ("can we have the photos on the right side of the hero"),
   so if a left-hand version is ever wanted again: it is `order: -1` on
   .pv3g__photowrap with margin-left: 0 / margin-right: clamp(16px, 2vw, 30px),
   plus .pv3g__wm mirrored to `left`, both inside a min-width: 1301px query —
   below that product-v3.css hides the photo and the copy runs full width, so
   there is nothing to flip. */

/* 2. THE CAROUSEL. A plain stack of four <img> crossfading on a timer; the
   inline script at the foot of martyns-law.html moves .is-on along.
   The radius, clipping and drop shadow move OFF the images and ON to the
   stack — on the images they would be drawn four times over, and the shadow
   of the outgoing photo would show through the incoming one mid-fade. */
.ml-hero2 .mlcar {
  position: relative;
  height: 100%;
  aspect-ratio: 1.1 / 1;
  border-radius: clamp(18px, 2vw, 28px);
  overflow: hidden;
  box-shadow: 0 40px 90px rgba(0, 16, 20, 0.38);
}
.ml-hero2 .mlcar__shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;     /* .pv3g__photo pins 1.1/1; the stack owns that now */
  object-fit: cover;
  border-radius: 0;
  box-shadow: none;
  opacity: 0;
  transition: opacity 900ms var(--hv2-ease);
}
.ml-hero2 .mlcar__shot.is-on { opacity: 1; }
/* each photo has its subject in a different place — same crops as the home
   page's four tiles, so the two pages frame them identically */
.ml-hero2 .mlcar__shot:nth-child(1) { object-position: 60% 50%; }
.ml-hero2 .mlcar__shot:nth-child(2) { object-position: 55% 50%; }
.ml-hero2 .mlcar__shot:nth-child(3) { object-position: 50% 55%; }
.ml-hero2 .mlcar__shot:nth-child(4) { object-position: 0% 50%; }

@media (prefers-reduced-motion: reduce) {
  .ml-hero2 .mlcar__shot { transition: none; }
}


/* --- phone: readable labels and finger-sized targets ---------------------- */
/* Rebecca, 22/10/2026, after the first proper look at the site on a phone.
   Three things an audit at 390px turned up. None of them breaks the layout —
   the site has no horizontal scroll and nothing is cut off — but all three
   make it harder to use with a thumb than it needs to be.

   ⚠ SCOPED TO 620px, the phone breakpoint this file already uses elsewhere.
   Deliberately NOT applied to tablets: at 621-900px the footer is still
   multi-column and 44px rows would leave it full of gaps. If a tablet pass is
   ever wanted, `@media (hover: none)` is the honest query for a touch screen,
   but it cannot be checked by narrowing a desktop window, which is how anyone
   is actually going to test this. */
@media (max-width: 620px) {

  /* 1. The .eyebrow pill ships at 10px uppercase with 0.12em tracking, which
     is the design system's own value and fine on a desktop. On a phone it is
     under the 12px floor and genuinely hard to read — it is what "Partner
     network" and "Our network" use on the two partner pages. Tracking comes in
     slightly so the wider type does not push the pill out of its row.
     ⚠ Only this site's copy changes; grouped.org.uk keeps 10px. */
  .hv2 .eyebrow {
    font-size: 12px;
    letter-spacing: 0.09em;
  }

  /* 2. Footer links were 19px tall — the height of the text and nothing more,
     stacked on a 9px gap. The gap moves onto the link itself so each one is a
     44px row you can hit without aiming, and the rhythm stays even.
     Scoped to .foot2__grid ul so the social icon, the brand blurb and the
     legal row below are untouched by this rule. */
  .hv2 .foot2__grid ul { gap: 0; }
  .hv2 .foot2__grid ul a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* the legal row and the contact band's email line, same problem */
  .hv2 .fxb__links a,
  .hv2 .cb__alt {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* 3. Carousel dots: the comment in home-v2.css calls 24px "the target", and
     on a mouse it is. The visible dot is drawn by ::before and does not move,
     so this grows only the hit area. */
  .hv2 .tcar__dot { width: 44px; height: 44px; }

  /* 4. The terms tick box on the trial and partner forms was 18px. The <label>
     wraps the whole row so the text already toggles it, but the box itself is
     what people aim at, so it grows too. margin keeps it on the first line of
     the sentence beside it. */
  .hv2 .auth-consent input[type="checkbox"] {
    width: 24px;
    height: 24px;
    margin-top: 1px;
  }
}

/* --- phone, second pass: the four the first pass left ---------------------- */
/* Rebecca, 22/10/2026: "fix those four too". Same 620px scope and the same
   reasoning as the block above. */
@media (max-width: 620px) {

  /* 1. A BUTTON RUNNING OFF THE SCREEN. The launch campaign hero's CTA reads
     "Book a demo to secure the launch deal" — 364px of label in a 318px column,
     and .btn is `white-space: nowrap`, so it could not wrap and hung 10px past
     the right edge, clipped. Letting buttons wrap below 620px fixes it without
     touching the copy. `normal` only wraps when there is not room, so every
     button that already fits on one line still does. */
  .hv2 .btn {
    white-space: normal;
    text-align: center;
  }
  /* ⚠ EXCEPT THE ONE IN THE MENU BAR. The rule above is right for buttons in
     the body, which sit in a column and have room to take a second line. The
     nav CTA sits in a fixed-height bar beside the logo and the burger, and
     with wrapping on it broke "Book a demo" across two lines and grew the bar.
     Its label is short and always fits, so it keeps nowrap. */
  .hv2 .nv__cta { white-space: nowrap; }

  /* 2a. STANDALONE CTA LINKS. These are inline-flex rows, not prose, so they
     take a real height. 23px -> 44px. */
  .hv2 .dm-tile__go,
  .hv2 .partner-card__link {
    min-height: 44px;
  }

  /* 2b. LINKS INSIDE A SENTENCE — "Email our team", "Sign in", "Terms",
     "Privacy Policy". These must NOT be given a height: they sit mid-paragraph
     and a 44px line box would space the prose out.
     ⚠ padding-block on an INLINE element grows the clickable box WITHOUT
     moving anything, because inline boxes overlap their neighbours rather than
     pushing them apart. That is the whole trick here. Do not "tidy" this into
     a min-height — it would reflow every paragraph it touches. */
  .hv2 .auth-foot a,
  .hv2 .auth-consent a {
    padding-block: 12px;
  }

  /* 3. THE "VERIFY YOU'RE HUMAN" BOX on the partner application — a drawn 26px
     square with a tick, styled in that page's own <style> block.
     ⚠ FIRST ATTEMPT WAS WRONG AND IS WORTH RECORDING. The obvious trick is an
     invisible `::after { position:absolute; inset:-9px }` to spread the hit
     area without moving the square. The rule applies cleanly — computed style
     confirms a 40x40 absolutely-positioned pseudo with pointer-events:auto —
     and it still does NOT work, because this is a <button>, and Chrome does
     not hit-test the pseudo-elements of a form control. A tap 8px outside the
     square lands on the parent div, which was proved with elementFromPoint,
     not assumed. Do not reinstate it.
     So the square itself grows, to 36px. Not the full 44, but it is a tick box
     beside one line of text and 44 would read as a panel. The rest of the gap
     is closed by the label: the page's script now toggles on the words
     "Verify you're human" too, which makes the real target the whole row. */
  .hv2 .human-check__box { width: 36px; height: 36px; }
  .hv2 .human-check__label { cursor: pointer; }

  /* 4. THE MENU-BAR LOGO was 30px tall — the height of the image. The image
     does not change size; the link grows around it. The bar is ~60px, so there
     is room for 44 without the header moving. */
  .hv2 .nv__logo { min-height: 44px; }
}
