/* ==========================================================================
   TISA BUSINESS - DESIGN SYSTEM + HEADER
   --------------------------------------------------------------------------
   Light, enterprise. Purple is an ACCENT, not the field. Every rule is
   anchored on .tb-header / .tb-mobile so it outranks the scoped reset that
   business/index.php emits after this block.
   ========================================================================== */
:root{
/* NOTE 2026-08-28: every COLOUR token that used to live here was a leftover
   from the pre-flip palette and was silently overridden by the block further
   down, so the file carried two contradictory palettes and only load order
   decided. They are deleted. What remains here is structural only: typefaces,
   radii, easing, layout measures and the two logo colours. The palette lives
   in ONE place, in body.tb-body below. */

    /* ----------------------------------------------------------------------
       INDIGO. Agreed 2026-08-25. The logo icon is not one purple: sampled,
       it runs #6108C0 indigo at the top down to #9E0493 magenta at the
       bottom. tisa.one (personal) spends only the warm magenta half, plus
       #FFD700. Business takes the cool indigo half of the same icon, so the
       two sites are visibly the same company and never mistaken for each
       other. The --tb-purple-* names are kept so nothing downstream breaks.
       ---------------------------------------------------------------------- */

    /* ======================================================================
       THE TISA BUSINESS PALETTE, set by Santosh 2026-08-27 and applied across
       the whole site, landing page included.

         MIDNIGHT NAVY  #081A2B   the dark ground and the ink
         PORCELAIN      #F7F8F6   the primary light ground, not pure white
         SIGNAL BLUE    #6108C0   actions, links, active states. USED SPARINGLY,
                                  so that it feels important when it appears
         TITANIUM       #A7B0BA   fine borders, connection lines, structure

       Every value below is measured, not chosen by eye.

       THREE RULES THAT CAME OUT OF THE MEASUREMENTS, do not break them:
       1. TITANIUM IS NOT A TEXT COLOUR ON A LIGHT GROUND. #A7B0BA on Porcelain
          is 2.06:1 and fails outright. It is for hairlines, rules and
          structure. On the navy ground it is 8.02:1 and is fine as text there.
       2. SIGNAL BLUE IS NOT A TEXT COLOUR ON NAVY. It is 3.5:1, large text
          only. On the dark ground use Porcelain, Titanium, or the lifted blue.
       3. THE LOGO COLOURS NEVER TOUCH THE NAVY. Logo indigo is 1.93:1 on navy
          and the magenta is 2.42:1: both invisible. They are a TYPOGRAPHIC
          accent for a light ground only (8.56:1 and 6.82:1 on Porcelain), used
          on a word, never as a fill and never as a background gradient. The
          gradient stays in the logo mark itself, so the interface keeps ONE
          action colour and the page never reads as two competing brands.
       ---------------------------------------------------------------------- */

    /* --- The four named brand colours --- */
    /* the logo mark, for a word of type on a LIGHT ground only */
    /* The two TISA identity colours, per Santosh 2026-08-28. NOTE: an earlier
       note in this project recorded the logo gradient as #6108C0 -> #9E0493;
       these are the values he has now specified as exact. Declared but not
       referenced anywhere - the accent tokens below carry the brand. */
    --tb-logo-indigo:#6108C0;
    --tb-logo-magenta:#9E0493;

    /* --- Surfaces. Porcelain is the primary ground; white is now reserved for
       insets and anything that must lift off the page. The band ladder steps
       dL* 3.1 then 3.3, which matches the ladder already proven on the
       landing page. --- */      /* second band  15.28:1 for navy text */      /* third band   14.04:1 for navy text */         /* hairline, a light step of Titanium */

    /* --- Ink. Navy and two neutrals drawn down from it, so the greys belong
       to the same family as the ground rather than being flat. --- */   /* headings  16.5:1 on Porcelain */         /* body copy  7.1:1 on Porcelain */        /* labels. Measured on the DARKEST band, not
                                  just on Porcelain: 5.8 / 5.4 / 5.0 across
                                  the three grounds. #63707E passed on
                                  Porcelain and then failed at 4.04 on the
                                  third band, which is where labels sit. */

    /* --- The single action colour. Signal Blue. The --tb-purple-* names are
       kept as aliases so that twenty pages repaint from this one block
       instead of being edited one by one. --- */
    /* Signal Blue itself is 4.73:1 on Porcelain and 4.02:1 on the third
       band, so as SMALL TEXT it misses AA on the darker grounds. This is
       Signal darkened by the minimum needed to pass everywhere: RGB 33,89,224
       against 40,100,240, a shift no eye will read as a different colour.
       5.5 / 5.1 / 4.7 as text across the three bands, and white on it is
       5.88:1 for button fills. --tb-signal keeps the exact brand value. */       /* hover and pressed, white on it 6.83:1 */       /* eyebrow pills. Pill TEXT must be         /* status ONLY. 4.96:1 on Porcelain. */

    /* --- The one dark moment per page --- */

    /* --- Type. ONE family, tuned by weight and tracking rather than by mixing
       two. Space Grotesk + Inter was the pairing the design standard itself
       names as the AI-default tell, and it is the reason the page read as
       competent rather than authored. Instrument Sans holds its shape at 60px
       and at 11px, has proper tabular figures, and almost nobody is using it.
       Both tokens are here so reverting is one line, not a hundred. --- */
    --tb-display:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
    --tb-text:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;

    /* --- Radius --- */
    --tb-r-xs:8px; --tb-r-sm:12px; --tb-r:16px; --tb-r-lg:24px; --tb-r-pill:999px;

    /* --- Elevation: soft, layered, never a hard drop --- */

    --tb-ease:cubic-bezier(0.16,1,0.3,1);
    /* ======================================================================
       THE CONTAINER SYSTEM, 2026-09-04e. ONE set of tokens for the whole site.

       --tb-max is the content line. 1240 -> 1560, per the MASTER STANDARD's
       1500-1650 band. Everything that reads it moves together: the shared
       header shell, the shared footer container, every page section and the
       landing hero's own centring expression.

       --tb-pad replaces a flat 40px desktop / 20px mobile with one fluid
       value that lands inside every band the standard specifies without a
       single extra media query:
         390 / 430 -> 20    (mobile 20-24)
         600       -> 25
         768       -> 32    (tablet 28-40)
         1440      -> 60    (desktop 48-64)
         1920      -> 81    (very large 64-96)
         2100+     -> 88    (capped)

       --tb-bleed is the SECOND line, and it is what stops the site coming
       apart when the window is very wide or the browser is zoomed out. A
       photograph that runs edge to edge is a legitimate device up to about a
       1920px screen; past that it becomes a sliver and the composition
       separates. Full-bleed elements are capped here and centred, so extra
       viewport becomes balanced outer whitespace instead of more image.
       SECTION BACKGROUNDS ARE NOT CAPPED - they still span the full window.
       Only CONTENT is.
       ====================================================================== */
    /* --- LARGE-SCREEN SCALE, 2026-09-04f ------------------------------
       A FLAT 1560 made the site read as a laptop layout floating inside a
       big monitor. Measured fill (content width / viewport) before:
         1366 92%  |  1440 92%  |  1680 93%  |  1920 81%  |  2560 61%
       The container now grows with the window and then stops:
         1366 92%  |  1440 92%  |  1680 92%  |  1920 89%  |  2560 78%
       and it is frozen at 2000 from about 2560 up, so ultra-wide still gets
       balanced outer whitespace rather than endless stretch.
       IT CHANGES NOTHING AT OR BELOW 1680. Up to there the viewport minus
       padding is the binding term and this expression never gets a look in,
       which is why the laptop composition is untouched by construction. */
    --tb-max:clamp(1560px, 800px + 46.9vw, 2000px);
    --tb-pad:clamp(20px, 4.2vw, 88px);
    /* UNCAPPED, 2026-09-15.  THIS WAS THE "WHY IS NOTHING FULL ON A BIG
       SCREEN" FAULT, and it is worth stating plainly because it was mine.
       This token is the max-width of every FULL-BLEED PHOTO BAND on the
       site - eight page files use it. At 2280px the bands filled the window
       at 1920 and below and then simply stopped: measured on the landing
       page, 2280 of 2560 (280px of ground down each side) and 2280 of 3440
       (1160px). So the same page looked edge to edge on a laptop and inset
       on a large monitor, which is exactly what he kept reporting.
       IT WAS CAPPED ON 2026-09-04e TO FIX A 25%-ZOOM FAULT. That fault was
       real but it was about CONTENT stretching - a copy column and a
       photograph ending up 3870px apart. Content is governed by --tb-max,
       which still caps at 2000px and still fixes it. A band photograph is
       cover-cropped: it cannot stretch, distort, or become unreadable at
       any width, so it never needed a ceiling and the ceiling is the only
       thing stopping the site filling a large screen.
       WHY 9999px AND NOT 100vw. 100vw INCLUDES the scrollbar, so a band
       declared 100vw on a scrolling page is about 15px wider than the
       content area and pushes a horizontal scrollbar onto every page. A
       large px value lets `max-width` fall back to the parent's own width,
       which is the content area, with no overflow. The expressions that
       read `min(100vw, var(--tb-bleed))` to compute a gutter now resolve to
       plain 100vw, which is the true centred gutter and is identical to the
       old value at every width up to 2280.
       It must still stay ABOVE --tb-max or a full-bleed photograph would
       end up narrower than the text it sits under. */
    --tb-bleed:9999px;
    /* THE READING MEASURE, 2026-09-04. --tb-max governs the page; this governs
       a line of prose inside it. Measured at 1920 the legal pages ran 92-99
       characters a line and several ledger values ran uncapped to 122, which
       is past any typographic standard and is the first thing that reads as
       unfinished on a page a buyer actually reads word by word.
       52ch, not 68: the ch unit here is the width of a figure, 0.6875em, well
       wider than the average lowercase advance of about 0.5em, so 68ch
       rendered as 93 real characters a line. 52ch lands the whole site at
       roughly 72 characters, the top of the comfortable range, which is the
       right end of it for dense legal copy. Being in ch and not px, it holds
       at 12px small print as well as at 19px standfirst. */
    --tb-measure:52ch;
}

body.tb-body{margin:0 !important;padding-top:0 !important;background:var(--tb-bg);}

/* ==========================================================================
   HEADER
   ========================================================================== */
.tb-header{position:sticky;top:0;z-index:900;background:var(--tb-white);border-bottom:1px solid var(--tb-line);transition:box-shadow 0.25s var(--tb-ease);}
.tb-header.tb-stuck{box-shadow:0 1px 0 var(--tb-line),0 8px 28px rgba(18,16,42,0.07);}
.tb-header a{text-decoration:none;}

/* --- NAVIGATION PALETTE, 2026-08-29. Scoped to the shared chrome only, so
   the page tokens below are untouched and nothing outside the header moves.
   The utility bar used --tb-bg-soft #F6F3FA, which is a lavender: at 12
   points of blue over red it reads as visibly purple against the white nav.
   --tbh-utility is the same idea two thirds of the way back to white:
   1.09:1 against the nav, so the two surfaces still separate, but the hue
   is a cool off-white rather than a tint. The action colour is TISA Blue,
   white on it at 10.6:1. Magenta appears in one place only: the hover state
   of a single word inside one dropdown. --- */
.tb-header,.tb-mobile{
    --tbh-utility:#F6F3FA;      /* Cool Off-White, not a fourth near-white */
    --tbh-tint:#F6F3FA;         /* Cool Off-White */
    --tbh-ink:#17151D;          /* the SAME ink as the body. Was #0F1B29, a navy-cast
                                   ink that made the header a different colour family
                                   from every page under it. 18.1:1 on white. */
    --tbh-nav:#56515F;          /* the SAME secondary as the body. Was #41505F, navy-cast. 7.7:1 on white */
    --tbh-action:#6108C0;       /* TISA Blue. Actions and active marks */
    --tbh-action-hover:#4C0699;
    --tbh-accent:#9E0493;       /* 5.6:1 on white. One word, one dropdown */
}
.tb-header .tb-shell{max-width:var(--tb-max);margin:0 auto;padding:0 var(--tb-pad) !important;}

/* ---------- Utility bar ---------- */
.tb-header .tb-utility{background:var(--tbh-utility);border-bottom:1px solid var(--tb-line-soft);}
.tb-header .tb-utility-inner{display:flex;align-items:center;height:36px;font-family:var(--tb-text);font-size:12.5px;}
.tb-header .tb-switch{display:inline-flex;align-items:center;gap:24px;padding:0;}
/* The current area was a white pill with a ring and a drop shadow, which is
   three devices to say one thing. It is now weight and a 2px rule: the word
   is navy and semibold against a muted sibling, with a short TISA Blue mark
   under it. Dropping the pill also lets Personal sit flush with the logo
   below it, so the header has one left edge instead of two. */
.tb-header .tb-aud{position:relative;display:inline-flex;align-items:center;height:24px;padding:0 !important;color:var(--tbh-nav);font-weight:500;transition:color 0.2s var(--tb-ease);}
.tb-header .tb-aud:hover{color:var(--tbh-ink);}
.tb-header .tb-aud[aria-current="page"]{color:var(--tbh-ink);font-weight:600;}
/* Anchored to the TEXT, not to the box. The utility control grows from 24px
   to 32px and then to a 44px touch target as the viewport narrows, and a
   marker pinned to bottom:0 detached from the word by ten pixels on a
   phone. Half a line plus 2px keeps the same gap at every size. */
.tb-header .tb-aud[aria-current="page"]::after{content:"";position:absolute;left:0;right:0;top:calc(50% + 10px);height:2px;background:var(--tbh-action);}
.tb-header .tb-utility-spacer{flex:1;}
/* TOUCH TARGET, pre-launch audit 2026-09-16. Measured at 2560 the Service
   Status link is 98x20, and it is a standalone control in the utility bar, not
   an inline link in a sentence, so WCAG 2.2 AA 2.5.8 wants 24x24 and it was
   4px short on the vertical. The mobile branch below already pinned a 32px
   min-height; the desktop one had nothing.
   THE HIT AREA GROWS, THE INK DOES NOT. A centred ::after overlay is the only
   fix that adds no height to a 44px utility bar whose vertical rhythm is
   already set - raising the link's own box would have pushed the bar. */
.tb-header .tb-status{position:relative;}
.tb-header .tb-status::after{content:"";position:absolute;left:0;right:0;top:50%;
    transform:translateY(-50%);height:24px;}
.tb-header .tb-status{display:inline-flex;align-items:center;gap:8px;color:var(--tbh-nav);font-size:12.5px;font-weight:500;transition:color 0.2s var(--tb-ease);}
.tb-header .tb-status:hover{color:var(--tbh-ink);}
.tb-header .tb-status .tb-dot{width:6px;height:6px;border-radius:50%;background:var(--tb-live);}

/* ---------- Main navigation ---------- */
.tb-header .tb-main-inner{display:flex;align-items:center;height:74px;gap:38px;}

.tb-header .tb-brand{display:inline-flex;color:var(--tb-ink);align-items:center;gap:13px;flex-shrink:0;}
.tb-header .tb-brand img{height:38px !important;width:38px !important;display:block;border-radius:9px;}
.tb-header .tb-brand-div{width:1px;height:22px;background:var(--tb-line);}
.tb-header .tb-brand-tag{font-family:var(--tb-text);font-size:13px;font-weight:600;letter-spacing:0.16em;text-transform:uppercase;color:var(--tbh-ink);}

.tb-header .tb-nav{display:flex;align-items:center;gap:2px;margin:0 !important;padding:0 !important;list-style:none;}
.tb-header .tb-nav-item{position:relative;}
.tb-header .tb-nav-link{display:inline-flex;align-items:center;gap:7px;height:74px;padding:0 14px !important;font-family:var(--tb-text);font-size:15px;font-weight:500;color:var(--tbh-nav);background:none;border:none;cursor:pointer;white-space:nowrap;transition:color 0.2s var(--tb-ease);}
/* QA 2026-09-08: the three dropdown triggers carry a chevron inside their
   padding box, so the optical gap after them measured 7px wider than the gap
   after a plain text item. index.php has carried this correction since
   2026-08-31 as a page rule, which left the shared header 24px wider on the
   other 29 pages - the nav row shifted when you moved off the landing page.
   The rule lives here now and the page copy has been removed. */
.tb-header button.tb-nav-link{padding-right:7px !important;gap:6px !important;}
.tb-header .tb-nav-link:hover,.tb-header .tb-nav-link[aria-expanded="true"]{color:var(--tbh-ink);}
/* Underline that grows from the centre: the only nav flourish */
.tb-header .tb-nav-link::after{content:"";position:absolute;left:14px;right:14px;bottom:0;height:2px;background:var(--tbh-action);transform:scaleX(0);transition:transform 0.24s var(--tb-ease);}
.tb-header .tb-nav-link:hover::after,.tb-header .tb-nav-link[aria-expanded="true"]::after{transform:scaleX(1);}
.tb-header .tb-caret{font-size:9px;opacity:0.5;transition:transform 0.25s var(--tb-ease);}
.tb-header .tb-nav-link[aria-expanded="true"] .tb-caret{transform:rotate(180deg);opacity:1;}

.tb-header .tb-actions{margin-left:auto;display:flex;align-items:center;gap:10px;}
.tb-header .tb-signin{display:inline-flex;align-items:center;gap:7px;height:40px;padding:0 12px !important;font-family:var(--tb-text);font-size:15px;font-weight:500;color:var(--tbh-nav);background:none;border:none;border-radius:var(--tb-r-xs);cursor:pointer;white-space:nowrap;transition:color 0.2s var(--tb-ease),background 0.2s var(--tb-ease);}
.tb-header .tb-signin:hover{color:var(--tbh-ink);background:var(--tbh-tint);}
/* Same box, same 8px radius, same 42px height. What goes is the resting
   shadow, the lift on hover and the magenta hover fill: a quote button on
   a telecoms header should not move. Hover is the same blue, deeper. */
.tb-header .tb-cta{display:inline-flex;align-items:center;height:44px;padding:0 22px !important;font-family:var(--tb-text);font-size:15px;font-weight:600;color:#fff;background:var(--tbh-action);border-radius:var(--tb-r-xs);white-space:nowrap;transition:background 0.22s var(--tb-ease);}
.tb-header .tb-cta:hover{background:var(--tbh-action-hover);color:#fff;}

/* ---------- Dropdown panels ---------- */
.tb-header .tb-panel{position:absolute;top:100%;left:-4px;opacity:0;visibility:hidden;transform:translateY(-6px);transition:opacity 0.2s var(--tb-ease),transform 0.2s var(--tb-ease),visibility 0.2s;background:var(--tb-white);border:1px solid var(--tb-line);border-radius:var(--tb-r);box-shadow:var(--tb-e3);padding:8px !important;z-index:60;}
.tb-header .tb-nav-item.tb-open .tb-panel,.tb-header .tb-actions .tb-open .tb-panel{opacity:1;visibility:visible;transform:translateY(0);}
.tb-header .tb-panel-solutions{width:600px;display:grid;grid-template-columns:1fr 1fr;gap:2px;}
.tb-header .tb-panel-foot{grid-column:1 / -1;display:flex;align-items:center;gap:8px;margin-top:6px;padding:13px !important;border-top:1px solid var(--tb-line);font-family:var(--tb-text);font-size:13.5px;font-weight:500;color:var(--tb-muted);}
/* The one place magenta is allowed to appear, and only on hover: at rest
   this word carries the same blue as every other action in the header, so
   the open panel has ONE accent, not two competing ones. */
.tb-header .tb-panel-foot strong{font-weight:600;color:var(--tbh-action);transition:color 0.18s var(--tb-ease);}
.tb-header .tb-panel-foot:hover strong{color:var(--tbh-accent);}
.tb-header .tb-panel-foot .tb-ic{color:var(--tbh-action);}
.tb-header .tb-panel-foot i{font-size:10px;color:var(--tbh-accent);transition:transform 0.2s var(--tb-ease);}
.tb-header .tb-panel-foot:hover i{transform:translateX(3px);}
.tb-header .tb-panel-pricing{width:340px;}
.tb-header .tb-panel-resources{width:340px;}
.tb-header .tb-panel-signin{width:262px;left:auto;right:-4px;}
/* colour was never set here, so the anchor fell through to the UA default
   #0000EE. The two child spans paint themselves, which hid it - but the
   external-link glyph draws in currentColor and rendered browser blue. */
.tb-header .tb-mi{display:block;color:var(--tbh-ink);padding:11px 13px !important;border-radius:var(--tb-r-sm);transition:background 0.16s var(--tb-ease);}
.tb-header .tb-mi:hover,.tb-header .tb-mi:focus-visible{background:var(--tbh-tint);}
.tb-header .tb-mi-t{display:block;font-family:var(--tb-text);font-size:14.5px;font-weight:600;color:var(--tbh-ink);line-height:1.35;}
.tb-header .tb-mi-d{display:block;font-family:var(--tb-text);font-size:12.5px;font-weight:400;color:var(--tb-muted);line-height:1.45;margin-top:2px;}
.tb-header .tb-mi-ext{font-size:9px;opacity:0.4;margin-left:5px;}

/* ---------- Mobile ---------- */
.tb-header .tb-burger{display:none;align-items:center;justify-content:center;width:42px;height:42px;margin-left:auto;background:var(--tb-white);border:1px solid var(--tb-line);border-radius:var(--tb-r-xs);color:var(--tbh-ink);font-size:16px;cursor:pointer;padding:0 !important;}
.tb-mobile{display:none;position:fixed;inset:0;z-index:1200;background:var(--tb-white);overflow-y:auto;}
.tb-mobile.tb-mobile-open{display:block;}
.tb-mobile a{text-decoration:none;}
.tb-mobile .tb-mobile-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px !important;background:var(--tb-white);border-bottom:1px solid var(--tb-line);position:sticky;top:0;z-index:2;}
.tb-mobile .tb-brand{display:inline-flex;align-items:center;gap:11px;}
.tb-mobile .tb-brand img{height:34px !important;width:34px !important;border-radius:8px;}
.tb-mobile .tb-brand-div{width:1px;height:18px;background:var(--tb-line);}
.tb-mobile .tb-brand-tag{font-family:var(--tb-text);font-size:12px;font-weight:600;letter-spacing:0.16em;text-transform:uppercase;color:var(--tbh-ink);}
.tb-mobile .tb-mobile-close{width:42px;height:42px;background:var(--tb-white);border:1px solid var(--tb-line);border-radius:var(--tb-r-xs);font-size:17px;color:var(--tbh-ink);cursor:pointer;padding:0 !important;}
.tb-mobile .tb-mobile-body{padding:6px 20px 40px !important;}
.tb-mobile .tb-acc-btn{display:flex;align-items:center;justify-content:space-between;width:100%;padding:17px 0 !important;background:none;border:none;border-bottom:1px solid var(--tb-line);font-family:var(--tb-text);font-size:17px;font-weight:600;color:var(--tbh-ink);cursor:pointer;text-align:left;}
/* 0.4 on a 12px caret is close to invisible on a phone, and it is the only
   thing saying these three rows open. */
.tb-mobile .tb-acc-btn .tb-caret{width:1em;height:1em;opacity:0.62;transition:transform 0.25s var(--tb-ease);}
.tb-mobile .tb-acc-btn[aria-expanded="true"] .tb-caret{transform:rotate(180deg);}
/* An open group used to sit on the SAME left edge as the top-level items, so
   "Cloud PBX" and "Pricing" read as siblings. Indented, the group is obvious
   at a glance. Spacing, not a rule and not a box. */
.tb-mobile .tb-acc-panel{display:none;padding:4px 0 14px 14px !important;}
.tb-mobile .tb-acc-panel.tb-acc-show{display:block;}
.tb-mobile .tb-m-link{display:block;padding:17px 0 !important;border-bottom:1px solid var(--tb-line);font-family:var(--tb-text);font-size:17px;font-weight:600;color:var(--tbh-ink);}
.tb-mobile .tb-m-sub{display:block;padding:12px 0 !important;min-height:44px;
    display:flex;flex-direction:column;justify-content:center;}
.tb-mobile .tb-m-sub-t{display:block;font-size:15.5px;font-weight:600;color:var(--tbh-ink);}
.tb-mobile .tb-m-sub-d{display:block;font-size:13px;color:var(--tb-muted);margin-top:1px;}
.tb-mobile .tb-mobile-actions{margin-top:26px;}
.tb-mobile .tb-mobile-actions .tb-cta{display:flex;align-items:center;justify-content:center;height:52px;font-family:var(--tb-text);font-size:16px;font-weight:600;color:#fff;background:var(--tbh-action);border-radius:var(--tb-r-xs);}
.tb-mobile .tb-mobile-aud{display:flex;gap:8px;margin-top:24px;padding-top:20px !important;border-top:1px solid var(--tb-line);}
/* Two bordered tiles were the only boxes in an otherwise box-free menu. This
   is now the same device the utility bar uses at the top of every page: the
   current area in navy semibold over a short TISA Blue rule, the other one
   muted. One treatment for one idea, in both places it appears. */
.tb-mobile .tb-mobile-aud{gap:26px;}
/* These two anchors carry no class, so body.tb-body a:not([class]) - which
   outranks a two-class selector - was painting Personal in link blue and
   hanging a border under BOTH of them. The bordered tiles used to hide that
   by setting their own border. (0,3,2) is what it takes to put it right. */
body.tb-body .tb-mobile .tb-mobile-aud a{border-bottom:0;color:var(--tbh-nav);}
body.tb-body .tb-mobile .tb-mobile-aud a[aria-current="page"]{color:var(--tbh-ink);}
.tb-mobile .tb-mobile-aud a{position:relative;flex:0 0 auto;text-align:left;
    padding:11px 0 !important;min-height:44px;display:inline-flex;align-items:center;
    font-family:var(--tb-text);font-size:15px;font-weight:500;color:var(--tbh-nav);}
.tb-mobile .tb-mobile-aud a[aria-current="page"]{color:var(--tbh-ink);font-weight:600;}
.tb-mobile .tb-mobile-aud a[aria-current="page"]::after{content:"";position:absolute;
    left:0;right:0;top:calc(50% + 11px);height:2px;background:var(--tbh-action);}

@media (max-width:1160px){
    /* THE MOBILE HEADER: brand, one commercial action, menu. The whole
       .tb-actions block used to be hidden here, which left a phone header
       with no way to act at all - every route to a quote was behind the
       burger. Sign In stays behind it, because it is not the commercial
       action; "Get a quote" comes out. It is the SAME button, not a new
       style: same fill, same radius, stepped down to a 38px control so it
       cannot compete with the 44px menu trigger beside it.
       Measured before enabling: at 390 the brand is 131px and the burger
       44px, leaving 175px for a 108px button. At 320 only 105px is left,
       which is not enough for a button that still reads as a button, so
       below 360 it is hidden again and the burger carries the action. */
    .tb-header .tb-nav{display:none;}
    .tb-header .tb-actions{display:flex;margin-left:auto;gap:0;}
    .tb-header .tb-actions .tb-nav-item{display:none;}
    /* 44px, not 38px. MOBILE AUDIT 2026-09-10: this is the only commercial
   control in the header and it measured 38px on every screen from 320 to
   1024 - the smallest button on the page, on the pages where it matters
   most, while the sites own quiet links are all min-height:44px. 42px
   above 1024 and 38 below was backwards: the touch target should be the
   larger one. It fits: the mobile header is 74px tall. */
.tb-header .tb-cta{height:44px;padding:0 16px !important;font-size:14px;}
    .tb-header .tb-burger{display:inline-flex;margin-left:12px;}
    .tb-header .tb-main-inner{height:66px;gap:0;}
}
@media (max-width:640px){
    /* --tb-pad:20px was here. The clamp above already resolves to 20px at
       every width below 480, so the override is redundant and removing it
       takes one more breakpoint out of the 60 the audit counted. */
    .tb-header .tb-brand img{height:34px !important;width:34px !important;}
    .tb-header .tb-brand-tag{font-size:11.5px;}
}

/* Touch targets. On a phone the utility bar items were 20-24px tall, which is
   at or under the WCAG 2.2 minimum and unpleasant to hit. The bar grows and the
   targets grow with it. */
@media (max-width:359px){
    /* Not enough horizontal room. Nothing is squeezed: the action is dropped,
       and the menu trigger takes back the auto margin that was holding it to
       the right edge - without it the burger collapsed against the wordmark. */
    .tb-header .tb-actions{display:none;}
    .tb-header .tb-burger{margin-left:auto;}
}
@media (hover:none),(max-width:1160px){
    .tb-header .tb-utility-inner{height:44px;}
    .tb-header .tb-aud{height:32px;padding:0 !important;}
    .tb-header .tb-status{min-height:32px;padding:0 4px !important;}
    .tb-header .tb-brand{min-height:44px;}
}

/* ---------- Accessibility ---------- */
.tb-skip{position:absolute;left:-9999px;top:0;z-index:2000;padding:12px 20px;background:var(--tb-purple);color:#fff;font-family:var(--tb-text);font-size:14px;font-weight:600;}
.tb-skip:focus{left:0;}
.tb-header a:focus-visible,.tb-header button:focus-visible,.tb-mobile a:focus-visible,.tb-mobile button:focus-visible{outline:2px solid var(--tbh-action);outline-offset:3px;border-radius:var(--tb-r-xs);}
@media (prefers-reduced-motion:reduce){
    .tb-header *,.tb-mobile *{transition:none !important;animation:none !important;}
}

/* ============================================================================
   TB-FOOTER-V1  - the shared site footer, restyled for Business only.
   Scoped to body.tb-body, which only header-business.php emits, so the
   personal site keeps the footer it has. Reasons for the restyle:
     - the page already spends its ONE dark moment on the PSTN switch-off band,
       so a second dark slab at the bottom breaks the page rhythm;
     - the shared footer carries a gold second accent, which the business
       system does not have;
     - it set its own type (Space Grotesk everywhere, 1.05rem contact rows),
       so the last thing a buyer reads was in a different voice from the rest.
   Everything below is one accent, hairlines, and the page's own type ramp.
   ========================================================================= */
body.tb-body footer.ft{
    /* Deep Midnight Navy. The brief said "selectively for depth, footer
       areas". The footer is written entirely in tokens, so the inverse ink
       run below flips every descendant with it. */
    background:#320561 !important;
    --tb-ink:#FFFFFF;
    --tb-body:#E9DCF8;
    --tb-muted:#E9DCF8;
    --tb-accent-text:#FFFFFF;
    --tb-accent-text-hover:#FFFFFF;
    --tb-purple:#9E0493;
    --tb-line:rgba(255,255,255,0.16);
    --tb-line-soft:rgba(255,255,255,0.10);
    --tb-line-strong:rgba(255,255,255,0.22);
    --tb-white:rgba(255,255,255,0.05);
    --tb-titanium:#E9DCF8;
    /* THE RULE IS BACK, 2026-09-02, and the reason it was removed is gone. It
       read "the final CTA section and the footer are two different navies, so
       the tonal step already states the boundary". They are no longer two
       navies: the close and the footer are now the SAME Midnight Ink, on
       purpose, so the page ends as one deliberate dark mass rather than a step
       nobody could see - the old one measured 1.11. With no tonal step left,
       space plus one hairline states the boundary. */
    border-top:1px solid rgba(255,255,255,0.12) !important;
    color:#E9DCF8 !important;
    font-family:var(--tb-text) !important;
    padding:64px 0 0 !important;
    overflow:visible !important;
}
body.tb-body footer.ft .ft-glow{display:none !important;}
body.tb-body footer.ft > .container{max-width:var(--tb-max) !important;padding:0 var(--tb-pad) !important;}
body.tb-body footer.ft .ft-top{gap:64px !important;margin-bottom:48px !important;}

/* Brand */
/* 10px was the last value on the page that is not on the 8/12/16/24 scale */
body.tb-body footer.ft .ft-logo{width:40px !important;height:40px !important;border-radius:var(--tb-r-xs) !important;}
body.tb-body footer.ft .ft-logo-row{gap:12px !important;margin-bottom:20px !important;}
body.tb-body footer.ft .ft-brand-name{
    font-family:var(--tb-display) !important;
    font-size:24px !important;font-weight:700 !important;color:var(--tb-ink) !important;
    letter-spacing:-0.02em !important;
}
body.tb-body footer.ft .ft-brand-tag{
    font-family:var(--tb-text) !important;
    font-size:11.5px !important;font-weight:600 !important;color:var(--tb-muted) !important;
    letter-spacing:0.16em !important;margin-top:3px !important;
}

/* Socials: hairline squares, not filled chips */
body.tb-body footer.ft .ft-socials{gap:8px !important;}
/* Lighter: the fill and the 0.16 border together made two marks where one
   will do. 38px is kept - the control stays a comfortable target. */
body.tb-body footer.ft .ft-social{
    width:38px !important;height:38px !important;border-radius:var(--tb-r-xs) !important;
    background:transparent !important;border:1px solid var(--tb-line-soft) !important;
    color:var(--tb-muted) !important;font-size:15px !important;box-shadow:none !important;
    transition:color 0.2s var(--tb-ease),border-color 0.2s var(--tb-ease);
}
/* not magenta: #9E0493 is the extremely limited signature accent and two
   social buttons are not where it should be spent */
body.tb-body footer.ft .ft-social:hover{
    background:transparent !important;border-color:var(--tb-ink) !important;
    color:var(--tb-ink) !important;transform:none !important;box-shadow:none !important;
}

/* Link columns.
   FOUR COLUMNS ON BUSINESS, NOT FIVE, 2026-09-16. The shared stylesheet sets
   repeat(5,1fr) because the personal footer has five link columns. The
   business footer lost its Personal column on Vinay's instruction and the
   fifth track stayed behind as 195px of empty ground at 1440 and 296px at
   2560, hard against the right edge where a void is most visible. The count
   lives with the markup that produces it, so it is set here, in the sheet
   only business pages load, and the personal footer is untouched. */
body.tb-body footer.ft .ft-links-grid{grid-template-columns:repeat(4,1fr) !important;gap:32px !important;}
body.tb-body footer.ft .ft-col-title{
    font-family:var(--tb-text) !important;
    font-size:11.5px !important;font-weight:700 !important;color:var(--tb-ink) !important;
    letter-spacing:0.14em !important;margin:0 0 16px 0 !important;padding:0 !important;
}
body.tb-body footer.ft .ft-col-title::after{display:none !important;}
body.tb-body footer.ft .ft-list li{margin:0 0 4px 0 !important;}
/* 32px of height on every footer link. They measured 23px, which is under the
   24px WCAG 2.5.8 target size and well under a comfortable thumb. */
/* NO PERMANENT UNDERLINE. Every footer link carried border-bottom:1px in
   currentColor from the classless-anchor rule, so thirteen navigation links
   were permanently ruled. Underline is an interaction state here, not a
   resting one; the links stay 32px tall for WCAG 2.5.8. */
body.tb-body footer.ft .ft-list a{
    font-family:var(--tb-text) !important;
    font-size:14.5px !important;font-weight:400 !important;color:var(--tb-body) !important;
    display:inline-flex !important;align-items:center !important;min-height:32px !important;
    border-bottom:0 !important;text-decoration:none !important;
}
body.tb-body footer.ft .ft-list a:hover,
body.tb-body footer.ft .ft-list a:focus-visible{
    color:var(--tb-ink) !important;transform:none !important;
    text-decoration:underline !important;text-decoration-thickness:1px !important;
    text-underline-offset:4px !important;}
/* measured 0px: something upstream suppresses the ring, so this needs the
   same weight as everything else in this override block */
/* MEASURED under a real Tab walk: the ring resolved to 0px because something
   upstream zeroes outline-width on :focus, and only :focus-visible was being
   answered here. Both pseudos now carry it. */
body.tb-body footer.ft a:focus,
body.tb-body footer.ft a:focus-visible{outline:2px solid #FFFFFF !important;outline-offset:3px !important;border-radius:3px !important;}
body.tb-body footer.ft .ft-bottom a,
body.tb-body footer.ft .ft-contact-item{border-bottom:0 !important;text-decoration:none !important;}
body.tb-body footer.ft .ft-bottom a:hover,
body.tb-body footer.ft .ft-bottom a:focus-visible{
    text-decoration:underline !important;text-underline-offset:4px !important;}

/* Contact column: the phone number is a conversion path, so it reads first */
body.tb-body footer.ft .ft-contact-list{gap:12px !important;}
body.tb-body footer.ft .ft-contact-item{gap:11px !important;}
body.tb-body footer.ft .ft-contact-item i{
    width:32px !important;height:32px !important;border-radius:var(--tb-r-xs) !important;
    background:var(--tb-purple-soft) !important;border:none !important;
    color:var(--tb-purple) !important;font-size:13px !important;
}
body.tb-body footer.ft .ft-contact-item span{
    font-family:var(--tb-text) !important;
    font-size:15px !important;font-weight:500 !important;color:var(--tb-ink) !important;
}
body.tb-body footer.ft .ft-contact-item:hover i{
    background:var(--tb-purple-soft) !important;color:var(--tb-purple) !important;box-shadow:none !important;
}
body.tb-body footer.ft .ft-contact-item:hover span{color:var(--tb-purple) !important;}

/* Legal strip: a hairline, not a second slab */
body.tb-body footer.ft .ft-bottom-wrap{
    background:transparent !important;margin:0 !important;padding:0 !important;
    /* was --tb-line (0.16), the strongest hairline anywhere on the page for a
       boundary no more important than the FAQ row separators */
    border-top:1px solid var(--tb-line-soft) !important;
}
/* 34px left the copyright line under the floating chat launcher, which is
   fixed 14-20px off the bottom and 56px tall, so the last thing a visitor
   reads on every business page was half covered at full scroll. 92 clears
   the launcher and the Call Us 4 Free pill without touching either. */
body.tb-body footer.ft .ft-bottom{text-align:left !important;padding:26px 0 92px !important;line-height:1.7 !important;}
body.tb-body footer.ft .ft-company,
body.tb-body footer.ft .ft-address,
body.tb-body footer.ft .ft-copy{
    font-family:var(--tb-text) !important;font-size:13px !important;color:var(--tb-muted) !important;
    letter-spacing:0 !important;
}
body.tb-body footer.ft .ft-company{margin-bottom:6px !important;}
body.tb-body footer.ft .ft-company-name{font-weight:600 !important;color:var(--tb-ink) !important;}
body.tb-body footer.ft .ft-company-sep{margin:0 10px !important;color:var(--tb-line) !important;opacity:1 !important;}
body.tb-body footer.ft .ft-address{margin-bottom:6px !important;}

@media (max-width:992px){
    body.tb-body footer.ft{padding-top:48px !important;}
    /* .ft-top goes column at this width and its align-items:flex-start makes the
       link grid shrink to its content, stranding half the row. Stretch it. */
    body.tb-body footer.ft .ft-top{gap:40px !important;align-items:stretch !important;}
    /* TWO, NOT THREE: four columns across three tracks leaves one orphan on
       a second row under three-quarters of empty width. Two by two is even. */
    body.tb-body footer.ft .ft-links-grid{grid-template-columns:repeat(2,1fr) !important;width:100% !important;}
}
@media (max-width:768px){
    body.tb-body footer.ft > .container{padding:0 var(--tb-pad) !important;}
    body.tb-body footer.ft .ft-links-grid{grid-template-columns:repeat(2,1fr) !important;gap:28px !important;}
}
@media (max-width:576px){
    body.tb-body footer.ft{padding-top:40px !important;}
    body.tb-body footer.ft .ft-company-sep{display:none !important;}
    body.tb-body footer.ft .ft-company span{display:block !important;}
    body.tb-body footer.ft .ft-contact-item span{font-size:14.5px !important;white-space:nowrap !important;}
}


/* ------------------------------------------------------------------
   TOUCH TARGETS FOR INLINE PROSE LINKS. Added 2026-08-27.
   A link inside a sentence is still something a thumb has to hit.
   WCAG 2.5.8 wants 24px minimum and the house rule is 32px, but a
   bare inline <a> is only as tall as its text, around 19-21px.
   Vertical padding on an inline element grows its hit box without
   changing the line box, so the paragraph rhythm is untouched.
   Scoped to (hover:none) so desktop typography is not affected, and
   to prose containers only so buttons and rows keep their own sizing.
   ------------------------------------------------------------------ */
@media (hover:none){
    /* Every link inside a section EXCEPT the ones that already size
       themselves. The action classes across the estate all contain one of
       btn / cta / quiet / row / pill / book / -go / -link, and those are
       inline-flex with their own min-height, so adding padding would break
       them. Everything left is an inline text link that needs a bigger tap. */
    body.tb-body section a:not([class*="btn"]):not([class*="cta"]):not([class*="quiet"]):not([class*="row"]):not([class*="pill"]):not([class*="book"]):not([class*="-go"]):not([class*="-link"]):not(.tb-skip):not([class*="tab"]){
        /* 2026-09-25: was display:inline-block, which contradicts the note above:
           an inline-block's padding DOES grow the line box, so every line holding a
           link sat about 14px further from its neighbours on a phone. Inline keeps
           the taller hit box and leaves the paragraph rhythm alone. */
        padding-top:7px;
        padding-bottom:7px;
    }
}


/* ==========================================================================
   TB-DARK-V1 - THE BUSINESS DARK SYSTEM, SITE WIDE
   Added 2026-08-28.

   WHY THIS EXISTS. Measured before it: index.php and cloud-pbx.php were dark
   (#060B18 / #04070F) and every one of the other TWENTY-TWO business pages
   was light (#F7F8F6 with #424242 text). Every click from the homepage or the
   Cloud PBX page into any other page was a hard flip from near black to near
   white. That is the single most confusing thing on the site and no amount of
   per page polish fixes it.

   HOW IT WORKS, and why it is safe. Every business page is written in
   --tb-* tokens: measured across the set, 51 to 176 token uses per page and
   only SEVEN hardcoded white BACKGROUNDS in the entire site. --tb-white is
   used 48 times and every single one is a `background:`, so it is purely a
   surface token and can be redefined. So the whole site repaints from this
   one block.

   SCOPE. body.tb-body is emitted ONLY by includes/header-business.php, so the
   personal site is untouched. Page CSS is echoed at line 503, AFTER this, so
   any page can still override anything here.

   TO REVERT: delete this block. Nothing else changes.
   ========================================================================== */
/* THE PALETTE MOVED OUT, 2026-09-09, to assets/tb-tokens.css, so the
   standalone application form can read the same one instead of a pasted
   copy. It is linked immediately before this file in
   includes/header-business.php. Declaring a --tb-* colour here again
   would recreate the two-palettes problem the 2026-08-28 note describes. */

/* --- THE DEFAULT LINK COLOUR, KILLED ONCE. Several anchors in the set are
   block-level rows and cards whose CHILDREN paint the text, so the anchor
   itself never got a `color` and fell through to the UA default #0000EE.
   Nothing looked blue, because the children covered it - but any descendant
   drawing in currentColor (an arrow glyph, an SVG stroke, a border) picked
   up browser blue. Wrapped in :where() so this carries ZERO specificity: it
   beats the UA sheet and loses to every authored rule in the set. --- */
:where(body.tb-body a){color:inherit;}

/* --- ANY SECTION PAINTED WITH A DARK PUNCTUATION GROUND flips its inherited
   ink tokens. Custom properties inherit, so one class on the section is
   enough and every descendant follows. --- */
body.tb-body .tb-onDark{
    /* see the note on the page-scoped inverse run: the accent FILL must leave
       TISA Blue on a TISA Blue ground or the button is 1.0:1 */
    --tb-purple:#9E0493;
    --tb-purple-deep:#320561;
    --tb-ink:var(--tb-ink-inv);
    --tb-body:var(--tb-body-inv);
    --tb-muted:var(--tb-muted-inv);
    --tb-accent-text:var(--tb-accent-text-inv);
    --tb-accent-text-hover:#FFFFFF;
    --tb-line:rgba(255,255,255,0.16);
    --tb-line-soft:rgba(255,255,255,0.10);
    --tb-line-strong:rgba(255,255,255,0.22);
    --tb-white:rgba(255,255,255,0.05);
    --tb-zebra:rgba(255,255,255,0.05);
    --tb-live:#3DDC84;
    --tb-titanium:var(--tb-muted-inv);
    color:var(--tb-body-inv);
}

/* --- the shared chrome. It is already written in tokens, so it follows the
   flip on its own; these two only restore the separation the light theme got
   from a shadow it can no longer cast. --- */
body.tb-body .tb-header{background:#FFFFFF;border-bottom-color:var(--tb-line);}
body.tb-body .tb-header.tb-stuck{box-shadow:0 1px 0 var(--tb-line),0 8px 24px rgba(18,27,43,0.08);}
body.tb-body footer.ft{background:var(--tb-ground-deep);}
/* The shared footer paints a GOLD gradient underline under every column title
   (.ft-col-title::after). Gold is a banned family brand-wide and this was
   appearing on all 24 business pages. Scoped to body.tb-body so the personal
   site keeps its footer exactly as it is. */
body.tb-body footer.ft .ft-col-title::after{
  background:var(--tb-line) !important;background-image:none !important;}
/* The shared footer also carries two blurred decorative glows (.ft-glow).
   Glows are banned in the business system. Personal keeps them. */
body.tb-body footer.ft .ft-glow{display:none !important;}
/* The footer separator pipe measured 1.37:1 against the footer ground on every
   page, and it is decoration doing the job of punctuation. Hidden rather than
   recoloured: the three company facts already read as three facts on spacing.
   Scoped to body.tb-body so the personal footer is untouched. */
body.tb-body footer.ft .ft-company-sep{color:transparent !important;}
/* Three pages re-colour every link in a section and were reaching the skip
   link, which is the first thing a keyboard user lands on. Pinned. */
body.tb-body .tb-skip{background:var(--tb-purple) !important;color:#fff !important;}
/* 2026-09-02: the skip link measured 100x22 once focused at every width above
   900px - two pixels under the WCAG 2.2 SC 2.5.8 floor, and it is a real
   clickable control the moment a keyboard user tabs into the page. It is
   off-screen at left:-9999px until then, which is why earlier sweeps did not
   see it. The padding on the rule above never grew the box because the
   element computes to display:block with a 22px content height, so the height
   is set here instead. The <=900px block further down already did this. */
body.tb-body .tb-skip{min-height:44px;display:inline-flex;align-items:center;}
/* Inline SVG replaces Font Awesome. The library was 102KB to draw a caret, a
   hamburger, a close cross, an arrow and an external-link mark; these are the
   same five shapes at 0 bytes of network. currentColor means they inherit the
   token that already paints the text beside them. */
.tb-ic{width:1em;height:1em;flex:none;display:inline-block;vertical-align:-0.11em;}
.tb-caret{width:0.62em;height:0.62em;}
.tb-mi-ext{width:0.72em;height:0.72em;}
body.tb-body footer.ft .ft-ic{width:1.05em;height:1.05em;flex:none;display:inline-block;vertical-align:-0.15em;}
/* the one animated glyph the booking widget had (fa-spin) */
@keyframes tbSpin{to{transform:rotate(360deg);}}
.tb-spin{animation:tbSpin 0.9s linear infinite;}
@media (prefers-reduced-motion:reduce){.tb-spin{animation:none;}}
body.tb-body footer.ft .ft-company{gap:6px 20px;}


/* --- TABLES. Half of these pages are rate cards. Zebra striping that was a
   2% grey tint on white is invisible on navy, and a 1px light rule becomes a
   scratch, so both are re-cut for the dark ground. --- */
body.tb-body table{border-color:var(--tb-line);}
body.tb-body th{color:var(--tb-muted);border-color:var(--tb-line-strong);}
body.tb-body td{border-color:var(--tb-line-soft);color:var(--tb-body);}
body.tb-body tbody tr:nth-child(even) td{background:var(--tb-zebra);}
body.tb-body thead th{background:transparent;}

/* --- FORM CONTROLS. An input keeps the browser default white until it is
   told otherwise, which on this ground is a torch. --- */
body.tb-body input[type=text],body.tb-body input[type=email],
body.tb-body input[type=tel],body.tb-body input[type=number],
body.tb-body input[type=search],body.tb-body select,body.tb-body textarea{
    background:var(--tb-paper);color:var(--tb-ink);
    border-color:var(--tb-line-strong);
    -webkit-text-fill-color:var(--tb-ink);}
body.tb-body select option{background:#FFFFFF;color:#121B2B;}
body.tb-body ::placeholder{color:var(--tb-muted);opacity:1;}
body.tb-body input:focus-visible,body.tb-body select:focus-visible,
body.tb-body textarea:focus-visible{outline:2px solid var(--tb-accent-text);outline-offset:1px;}

/* --- one accent means one thing. A LABEL is muted; accent text means you can
   click it. Section labels across the set were painted with the action
   colour, so a reader could not tell a heading kicker from a link. --- */
body.tb-body [class$="-eyebrow"] [class$="-dot"],
body.tb-body [class$="-lab"] [class$="-dot"]{display:none !important;}

/* --- STICKY WAS DEAD SITE WIDE. includes/stylesheet.css sets
   body{overflow-x:hidden}, which makes body a scroll container and silently
   kills position:sticky on every descendant. voip-phones.php carried a
   one-page scoped fix and documented it; this is that fix, applied once for
   every business page, so sticky rails and sticky contents navs work.
   `clip` prevents the horizontal scroll `hidden` was there to prevent,
   without creating a scroll container. --- */
body.tb-body{overflow-x:clip;}
/* --- anchors were landing 20px BEHIND the header: measured header height is
   112px and eleven files declared scroll-margin-top:92px. Set once here so a
   page cannot get it wrong again. --- */
/* CORRECTED 2026-08-31. The 84px was measured landing anchors ~28px UNDER the
   header: the sticky header is 112px at EVERY width, not just above 900px, so
   84px was never enough on a phone. Both values now clear 112px with a small
   margin. Pages carrying a sticky sub-nav ON TOP of the header need more than
   this (112 + 52 + 1 = 165px, 157px on a phone) and declare their own
   `body.<page> section[id]{...}`: that selector is (0,2,2) and beats this one,
   which is (0,2,1) because `[id]` counts as a class. A page rule written
   `.<page> section` (0,1,1) or `body.<page> section` (0,1,2) LOSES to this
   block and will be silently ignored. */
body.tb-body section,body.tb-body [id]{scroll-margin-top:128px;}
@media (max-width:900px){body.tb-body section,body.tb-body [id]{scroll-margin-top:128px;}}
/* --- LABEL vs LINK. Across the set the accent painted the section kicker AND
   the links, so a reader could not tell which blue text was clickable. A
   label is muted; accent text means you can click it. --- */
body.tb-body [class$="-eye"],body.tb-body [class$="-eyebrow"],
body.tb-body [class$="-lab"],body.tb-body [class$="-kicker"]{color:var(--tb-muted);}



/* ==========================================================================
   TB-ARCS-V1 - ONE ARC PER PAGE, 2026-08-28.

   The audit found the set had exactly TWO ground strategies: a light
   three-band zebra (6 pages, with broadband.php and business-sims.php sharing
   the identical w-s-w-t-w-s-w sequence, and bulk-sms.php and
   pocket-office-sim.php sharing another) or flat white with hairlines
   (10 pages). Neither is an arc, and it is the main reason the set read as one
   template repeated.

   Every page below now has its OWN rising arc, and - this is the part that
   stops twenty dark pages becoming one dark page - THE BREAK IS IN A
   DIFFERENT PLACE ON EVERY ONE, chosen from that page's own argument:
   broadband breaks at its caveats, bulk-sms at its compliance duty,
   business-sims at "one invoice", voip-phones on a concession, contact at the
   form, the two rate cards in two different places so they stop being one page
   in two colours, and pocket-office breaks UPWARD, the only one that does.
   Two pages deliberately have no break at all.

   Grounds only ever RISE inside a movement, so no page zebras.
   Every ground lighter than #17274C carries lifted muted and accent-text
   tokens, because the defaults fail AA above that point.
   ========================================================================== */

/* --- index.php, THE LANDING PAGE  -  BREAK: at the PSTN switch-off, where the
   page stops selling and states a fact. Brought onto this system 2026-08-28.
   It had been running its own eleven-band near-black palette, three stacked
   override blocks deep, and was the ONLY page in the set not on Chart Room.
   That is what made every click from the homepage a hard flip.
   Dark opening (hero + trust plinth), light body, dark argument, dark close.
   --------------------------------------------------------------------------- */
/* --- THE LANDING RHYTHM, REDESIGNED 2026-09-02. -----------------------
   Replaces the three-canvas scheme (#F7F9FA neutral, #F6F3FA branded, #FAFBFC
   clean), which argued for 1.085 and 1.116 steps between three violet
   off-whites. The site now has TWO light surfaces by instruction, White and
   Cool Off-White, and the lilac is gone.

   Built on HIERARCHY, not alternation: three events and one ending, with quiet
   light in between.

     tbh  hero          #320561  LOCKED by instruction. The dark opening, and
                                 the one plum left on the site.
     tbn  trust strip   WHITE    FORCED light. Plum to Midnight Ink is 1.15 and
                                 plum to the old #320561 plinth was 1.11: both
                                 read as a rendering error rather than a
                                 transition, so NOTHING DARK MAY TOUCH THIS
                                 HERO. White lifts hardest out of it, 16.84.
     tbd  PSTN 2027     BLUE     THE BRAND MOMENT. 315px at 1440, the page's
                                 urgency beat, carrying the countdown and a CTA.
                                 Blue lands here and NOT on the flagship because
                                 tbp is 1113px, the tallest section on the page,
                                 and that much saturated blue would dominate the
                                 page and tire the reader. 315px is
                                 proportionate and unmissable.
     tbp  Cloud PBX     WHITE    the flagship takes its prominence from its SIZE
                                 and from following the blue, not from a colour.
     tbb  broadband     OFF-WHITE  quiet
     tbg  SIMs          WHITE      quiet
     tbz  messaging     OFF-WHITE  quiet
     tbc  the argument  INK      dark for authority, where the page makes its
                                 case for one provider.
     tbw  switching     WHITE    lifts out of the dark
     tbq  FAQ           OFF-WHITE  quiet
     tbt  the close     INK      and the footer is the SAME ink, so the page
                                 ends as one composed dark mass.

   Measured steps: plum-white 16.84, white-blue 10.63, blue-white 10.63,
   white-offwhite 1.07 (subtle on purpose, both sections quiet), offwhite-ink
   18.1, ink-white 19.4. --- */
body.business-landing-page .tbh{background:#320561 !important;}  /* hero - LOCKED, the one plum on the site */
body.business-landing-page .tbn{background:#FFFFFF !important;}  /* trust strip - forced light */
body.business-landing-page .tbd{background:#6108C0 !important;}  /* PSTN 2027 - THE brand moment */
body.business-landing-page .tbp{background:#FFFFFF !important;}  /* Cloud PBX, the flagship */
body.business-landing-page .tbb{background:#F6F3FA !important;}  /* broadband */
body.business-landing-page .tbg{background:#FFFFFF !important;}  /* SIMs */
body.business-landing-page .tbz{background:#F6F3FA !important;}  /* messaging */
body.business-landing-page .tbc{background:#320561 !important;}  /* why one provider - the argument */
body.business-landing-page .tbw{background:#FFFFFF !important;}  /* switching */
body.business-landing-page .tbq{background:#F6F3FA !important;}  /* FAQ */
body.business-landing-page .tbt{background:#320561 !important;}  /* the close - same ink as the footer */

/* --- broadband.php  -  BREAK: drops at the caveats, the one page that stops to warn you --- */
body.bbn-page .bn-h{background:#320561 !important;}
body.bbn-page .bn-p{background:#F6F3FA !important;}
body.bbn-page .bn-e{background:#FFFFFF !important;}
body.bbn-page .bn-w{background:#F6F3FA !important;}
body.bbn-page .bn-k{background:#320561 !important;}   /* THE BREAK - before you order */
body.bbn-page .bn-r{background:#F6F3FA !important;}
body.bbn-page .bn-q{background:#FFFFFF !important;}
body.bbn-page .bn-t{background:#320561 !important;}

/* --- bulk-sms.php  -  BREAK: at the compliance section, where the page stops selling --- */
/* .mx-o (the dark "outbound only" band) and .mx-g (the six guides) were
   DELETED from the page 2026-08-31 and their rungs go with them. The arc now
   runs navy / F8F7FA / F1EEF8 / F8F7FA x2 / F1EEF8 / navy: TWO navy anchors,
   hero and close, like every sibling product page, and the two light sections
   that share a ground (pricing and how it works) are one chapter. */
body.bmx-page .mx-h{background:#320561 !important;}
body.bmx-page .mx-d{background:#F6F3FA !important;}   /* overview */
body.bmx-page .mx-u{background:#FFFFFF !important;}   /* use cases, the step up */
body.bmx-page .mx-p{background:#F6F3FA !important;}   /* the commercials */
body.bmx-page .mx-s{background:#F6F3FA !important;}
body.bmx-page .mx-q{background:#FFFFFF !important;}
body.bmx-page .mx-t{background:#320561 !important;}

/* --- business-sims.php  -  BREAK: at FLEET MANAGEMENT, which is the argument
       for buying business SIMs at all rather than leaving people on their own
       consumer contracts. --- */
/* 2026-08-30, second pass. The standalone "one invoice" band was deleted: one
   sentence did not earn a whole section, and the benefit now sits inside fleet
   management as a capability. The arc was NOT patched around the hole. It was
   recomposed, because the old one alternated F8F7FA / F1EEF8 all the way down
   the page, which is the templated pattern.
   IT NOW RUNS IN CHAPTERS, not in stripes. Adjacent sections that answer one
   buyer question SHARE a ground, and the ground darkens as the page reaches
   each of its two arguments:
       navy        hero
       F8F7FA x2   what it is, what is included in it
       F1EEF8      allowances, the step up into the dark
       navy        FLEET MANAGEMENT, the break and the differentiator
       F8F7FA x2   what the price covers, what it costs
       F1EEF8 x2   which product, and the objections
       navy        the close
   Three navy anchors, exactly as index.php (hero / "why one provider" / close)
   and cloud-pbx.php (hero / by industry / close) already do it. The close was
   the ONLY one on Business ending light; every sibling page closes navy. */
body.bsim-page .bm-h{background:#320561 !important;}   /* anchor */
body.bsim-page .bm-d{background:#F6F3FA !important;}   /* chapter I - what it is */
body.bsim-page .bm-b{background:#F6F3FA !important;}
/* .bm-a (allowances) and .bm-l ("what your monthly price covers") were
   DELETED from the page 2026-08-30 and their rungs go with them. The arc is
   now navy / F8F7FA x2 / NAVY / F8F7FA / F1EEF8 x2 / navy: three anchors
   exactly as before, with fleet management still the one dark content band
   in the middle, and no adjacent pair repeating a tone. */
body.bsim-page .bm-f{background:#320561 !important;}   /* THE BREAK - fleet management */
body.bsim-page .bm-p{background:#F6F3FA !important;}   /* chapter II - the commercials */
body.bsim-page .bm-c{background:#FFFFFF !important;}   /* chapter III - the decision */
body.bsim-page .bm-q{background:#FFFFFF !important;}
body.bsim-page .bm-t{background:#320561 !important;}   /* the close */

/* --- pocket-office-sim.php  -  RECOMPOSED 2026-08-30. The mid-page navy band
   (.pk-r "what it replaces") was DELETED from the page in the 10/10 pass, and
   it is deliberately NOT replaced by another dark band: the page now carries
   two navy anchors, not three, because it lost a third of its sections and a
   third anchor on a shorter page reads as decoration.
   THE ARC RUNS IN THREE CHAPTERS between those anchors, and adjacent sections
   answering ONE buyer question share a ground rather than alternating:
       navy        hero
       F8F7FA x2   how it works, why use it     - understanding
       F1EEF8 x2   pricing, what is included    - the commercials, a step up
       F8F7FA x2   which product, questions     - the decision, a step back
       navy        the close
   --- */
body.pkt-page .pk-h{background:#320561 !important;}   /* anchor */
body.pkt-page .pk-d{background:#F6F3FA !important;}   /* chapter I - what it is */
body.pkt-page .pk-w{background:#F6F3FA !important;}
body.pkt-page .pk-p{background:#FFFFFF !important;}   /* chapter II - the commercials */
body.pkt-page .pk-f{background:#FFFFFF !important;}
body.pkt-page .pk-c{background:#F6F3FA !important;}   /* chapter III - the decision */
body.pkt-page .pk-q{background:#F6F3FA !important;}
body.pkt-page .pk-t{background:#320561 !important;}   /* the close, as every sibling page closes */

/* --- iot-sim-plans.php  -  NO BREAK, deliberately: a page with no price has no climax --- */
body.iotm-page .io-h{background:#320561 !important;}
body.iotm-page .io-u{background:#F6F3FA !important;}
body.iotm-page .io-w{background:#320561 !important;}
body.iotm-page .io-p{background:#FFFFFF !important;}
body.iotm-page .io-q{background:#FFFFFF !important;}
body.iotm-page .io-t{background:#320561 !important;}

/* --- voip-phones.php  -  BREAK: on a concession - the section arguing you may not need the product --- */
body.vph-page .vh-h{background:#320561 !important;}
body.vph-page .vh-m{background:#F6F3FA !important;}
/* .vh-q, which sat between them, was deleted from the page 2026-08-29 (all
   three of its answers restated prose within 200px of scroll), which left the
   BREAK and the closing band as two navy sections touching. The break moves to
   the middle rung so the page still reads navy, light, navy. */
body.vph-page .vh-o{background:#FFFFFF !important;}
body.vph-page .vh-d{background:#F6F3FA !important;}
body.vph-page .vh-t{background:#320561 !important;}

/* --- contact.php  -  BREAK DOWN at the form: the moment of work is the moment of focus --- */
body.bct-page .ct-h{background:#F6F3FA !important;}
body.bct-page .ct-w-sec{background:#FFFFFF !important;}
body.bct-page .ct-b{background:#F6F3FA !important;}   /* THE BREAK - the brief */
body.bct-page .ct-n{background:#320561 !important;}
body.bct-page .ct-s{background:#F6F3FA !important;}   /* was F3F0E9 = the footer's ground */

/* --- faqs.php  -  ONE break, then the six groups hold ONE ground - a reference must not zebra --- */
body.bfaq-page .fq-h{background:#320561 !important;}
body.bfaq-page .fq-g{background:#FFFFFF !important;}   /* all six groups, one ground */
body.bfaq-page .fq-none{background:#FFFFFF !important;}
body.bfaq-page .fq-e{background:#320561 !important;}

/* --- sms-pricing.php  -  Four sections: monotonic rise, the only event is the close --- */
body.smx-page .sx-h{background:#320561 !important;}
body.smx-page .sx-p{background:#F6F3FA !important;}
body.smx-page .sx-n{background:#FFFFFF !important;}
body.smx-page .sx-t{background:#320561 !important;}

/* --- business-international-rates.php  -  BREAK: at the search card, where the page stops arguing and starts answering --- */
body.bir-page .br-h{background:#320561 !important;}
body.bir-page .br-w{background:#F6F3FA !important;}   /* was ECE8E0, identical to br-p below it */
body.bir-page .br-p{background:#FFFFFF !important;}
body.bir-page .br-d{background:#320561 !important;}
body.bir-page .br-c{background:#F6F3FA !important;}   /* THE BREAK - the card you operate */
body.bir-page .br-q{background:#FFFFFF !important;}
body.bir-page .br-t{background:#F6F3FA !important;}

/* --- cloudpbx-international-rates.php  -  BREAK at the CONTROL band - deliberately a different place from its sibling page --- */
body.irx-page .ir-h{background:#320561 !important;}   /* was WHITE - the only hero in the set that was not navy */
body.irx-page .ir-b{background:#F6F3FA !important;}
body.irx-page .ir-f{background:#FFFFFF !important;}
body.irx-page .ir-d{background:#320561 !important;}   /* THE BREAK - the one thing the SIM page cannot say */
body.irx-page .ir-c{background:#F6F3FA !important;}
body.irx-page .ir-q{background:#FFFFFF !important;}
body.irx-page .ir-t{background:#320561 !important;}

/* --- business-roaming.php  -  BREAK UP at the Europe band --- */
body.brm-page .bm-h{background:#320561 !important;}
body.brm-page .bm-z{background:#F6F3FA !important;}
body.brm-page .bm-eu{background:#320561 !important;}   /* THE BREAK */
body.brm-page .bm-f{background:#F6F3FA !important;}
body.brm-page .bm-a{background:#FFFFFF !important;}
body.brm-page .bm-q-sec{background:#F6F3FA !important;}
body.brm-page .bm-e{background:#320561 !important;}

/* --- broadband-switch.php  -  BREAK UP at the single action: this page is a cul-de-sac and should look like one --- */
body.bbs-page .bs-h{background:#320561 !important;}
body.bbs-page .bs-s{background:#F6F3FA !important;}
body.bbs-page .bs-i{background:#FFFFFF !important;}
body.bbs-page .bs-w{background:#F6F3FA !important;}
body.bbs-page .bs-c{background:#320561 !important;}   /* THE BREAK */
body.bbs-page .bs-f{background:#F6F3FA !important;}

/* --- bespoke-pricing.php  -  The builder holds ONE ground while the reader works; the total drops --- */
body.bsp-page .bsp-hero{background:#F6F3FA !important;}   /* the sticky control bar below it is #FFFFFF; they used to be the same value */
body.bsp-page .bsp-section{background:#F6F3FA !important;}   /* all seven builder steps, one ground */
body.bsp-page .bsp-feat-section{background:#F6F3FA !important;}
body.bsp-page .bsp-bottom{background:#320561 !important;}   /* THE BREAK - the total */

/* --- roaming-zones.php  -  the five zones RISE, so tone encodes distance from home; then a hard reset --- */
body.rzn-page .rz-h{background:#320561 !important;}
body.rzn-page .rz-act{background:#F6F3FA !important;}
body.rzn-page .rz-z:nth-of-type(3){background:#FFFFFF !important;}   /* zone 1 */
body.rzn-page .rz-z:nth-of-type(4){background:#F6F3FA !important;}   /* zone 2 */
body.rzn-page .rz-z:nth-of-type(5){background:#FFFFFF !important;}   /* zone 3 */
body.rzn-page .rz-z:nth-of-type(6){background:#F6F3FA !important;}   /* zone 4 */
body.rzn-page .rz-z:nth-of-type(7){background:#FFFFFF !important;}   /* zone 5 */
body.rzn-page .rz-q-sec{background:#F6F3FA !important;}   /* THE RESET */
body.rzn-page .rz-e{background:#320561 !important;}

/* --- broadband-terms.php  -  clauses 1-17 are explanation and hold one ground; clause 18 is the reference copy you print, and it is the only break --- */
body.bbt-page .bt-mast{background:#320561 !important;}
body.bbt-page .bt-idx{background:#FFFFFF !important;}
body.bbt-page .bt-cl{background:#F6F3FA !important;}
body.bbt-page #c18{background:#FFFFFF !important;}   /* THE BREAK - the charge schedule */



/* --- the three business legal pages. cookies breaks at its one table (the
       only new information on the page); privacy breaks at breach
       notification (the one section describing failure rather than
       operation); terms does NOT break at all - a contract that changes
       tone partway through reads as if a clause is being softened. --- */
/* --- b-coverage-checker.php  -  rebuilt 2026-08-28. The map is the page, so
   the map gets the paper ground and the two dark moments bracket it. --- */
body.bc-page .bc-band-h{background:#320561 !important;}
body.bc-page .bc-band-m{background:#F6F3FA !important;}
body.bc-page .bc-band-l{background:#FFFFFF !important;}
body.bc-page .bc-band-t{background:#320561 !important;}

body.bck-page .bk-h{background:#320561 !important;}
body.bck-page .bk-t{background:#F6F3FA !important;}   /* THE BREAK: the table */
body.bck-page .bk-d{background:#FFFFFF !important;}
body.bck-page .bk-c{background:#F6F3FA !important;}

body.bpv-page .bp-h{background:#320561 !important;}
body.bpv-page .bp-p{background:#F6F3FA !important;}
body.bpv-page .bp-r{background:#FFFFFF !important;}
body.bpv-page .bp-b{background:#F6F3FA !important;}   /* THE BREAK: breach */
body.bpv-page .bp-t{background:#FFFFFF !important;}
body.bpv-page .bp-y{background:#F6F3FA !important;}

body.btm-page .bt-h{background:#320561 !important;}
body.btm-page .bt-s{background:#FFFFFF !important;}
body.btm-page .bt-k{background:#F6F3FA !important;}
body.btm-page .bt-o{background:#F6F3FA !important;}

/* --- why-tisa.php  -  BREAK at support: this page's one concession is that
       the desk closes at 5pm, and the arc drops where the page admits it --- */
body.wty-page .wt-h{background:#320561 !important;}
body.wty-page .wt-w{background:#F6F3FA !important;}
/* .wt-s and .wt-p-sec were deleted from the page 2026-08-29. .wt-i moves onto
   the middle rung so that it does not sit on the same ground as .wt-w above it. */
body.wty-page .wt-i{background:#FFFFFF !important;}
body.wty-page .wt-u{background:#320561 !important;}   /* THE BREAK - was WHITE, a 1.04:1 step, i.e. no break at all */
body.wty-page .wt-t{background:#F6F3FA !important;}   /* was F3F0E9 = the footer's ground */

/* --- the four support pages, one shared template. They break in FOUR
       DIFFERENT PLACES so that four pages on one template do not read as one
       page four times. The hero band is the darkest and the procedure opens
       UP as the reader gets their answer - the opposite direction to every
       product page. --- */
body.sup-page .su-h{background:#F6F3FA !important;}
body.sup-page .sup-rule{background:#FFFFFF !important;}
body.sup-page .sup-rule:nth-of-type(3){background:#F6F3FA !important;}
body.sup-page .sup-rule:nth-of-type(4){background:#FFFFFF !important;}
body.sup-page .sup-rule:nth-of-type(5){background:#F6F3FA !important;}
body.sup-page .sup-rule:nth-of-type(6){background:#FFFFFF !important;}
body.sup-page .sup-t{background:#320561 !important;}
body.sup-fwd .sup-rule:nth-of-type(2){background:#FFFFFF !important;}    /* breaks at the code ledger */
body.sup-kyn .sup-rule:nth-of-type(3){background:#F6F3FA !important;}    /* breaks at the two tracks */
body.sup-leave .sup-rule:nth-of-type(4){background:#FFFFFF !important;}  /* breaks at the comparator */
body.sup-sim .su-h{background:#FFFFFF !important;}                        /* breaks immediately: the dial bar is in the hero */
body.sup-sim .sup-rule:nth-of-type(2){background:#F6F3FA !important;}
body.sup-sim .sup-rule:nth-of-type(3){background:#FFFFFF !important;}
body.sup-sim .sup-rule:nth-of-type(4){background:#F6F3FA !important;}

/* --- support.php, the hub. Its own arc, and it must sit AFTER the generic
       sup-page ladder above or that ladder wins. The BREAK goes UP at the
       portals: the one moment the page hands a customer to their own account
       instead of to more reading. No other page in the set breaks up at a
       sign-in. --- */
body.sup-hub .su-h{background:#F6F3FA !important;}
/* #split was deleted from the page 2026-08-29; #tasks takes its rung so the
   hero does not sit on the same ground as the section under it. */
body.sup-hub #tasks{background:#FFFFFF !important;}
/* 2026-08-29: deleting #split left portals on the SAME rung as tasks, so the
   break the comment above describes did not exist. White is the lift: the arc
   now runs Porcelain, Lavender, White, Navy. */
body.sup-hub #portals{background:#FFFFFF !important;}   /* THE BREAK, upward */
body.sup-hub .sup-t{background:#320561 !important;}


/* --- UNCLASSED LINKS. A link written in prose with no class of its own fell
   through to the browser default #0000EE, which measures 1.89:1 on a dark
   closing band and is not the brand colour anywhere. This gives every
   unstyled link the accent that already means "you can click this", and
   because it is scoped to :not([class]) it cannot touch a styled control.
   The page stylesheet still loads after this file, so any page can override. */
/* ONE UNDERLINE MECHANISM, 2026-09-08. Santosh: "There are double underlines
   under some links, make sure you keep only one."
   THIS RULE WAS HALF OF EVERY ONE OF THEM. It drew the underline as a
   border-bottom, and any page rule that also underlined the same link with
   text-decoration produced TWO lines a few pixels apart - measured on the
   shared footer booking band (p.ft-book-alt a, so on every page that carries
   the band) and on prose links in business-roaming, business-sims and
   b-leaving-tisa. The two mechanisms cannot merge: a border and a decoration
   are drawn independently.
   text-decoration is now the ONLY mechanism, so a page that underlines a prose
   link collapses into this rule instead of stacking on top of it. It is also
   the better line: it skips descenders, and it follows the text when it wraps,
   which a border-bottom on an inline element does not. */
body.tb-body a:not([class]){color:var(--tb-accent-text);
    text-decoration:underline;text-decoration-thickness:1px;
    text-underline-offset:3px;border-bottom:0;}
body.tb-body a:not([class]):hover{color:var(--tb-accent-text-hover);}

/* ---------- THE SECTION RAILS ARE NAVIGATION, NOT PROSE ----------
   Six product pages carry a sticky rail of section links. Every one of them
   already says text-decoration:none, but the page selector is (0,2,1) and the
   rule above is (0,2,2), so the rule above won and EVERY item in every rail
   rendered underlined. The rails are designed to be quiet text with a 2px bar
   under the current section; with six underlines competing, that bar was
   invisible and there was no way to see where you were.
   This is the same specificity trap that underlined the price guide contents,
   the roaming zone jump links and the FAQ jump links. If a nav ever looks
   underlined again, it is this. 2026-09-09. */
body.tb-body .cx-rail a,
body.tb-body .bm-rail a,
body.tb-body .pk-rail a,
body.tb-body .bn-rail a,
body.tb-body .mx-rail a,
body.tb-body .vh-rail a{text-decoration:none;color:var(--tb-muted);}
/* THE SAME TRAP, ONE CASE LEFT, 2026-09-09. business-roaming's five zone cards
   are block links with no class of their own, so the rule above underlined the
   WHOLE CARD - zone label, destination count and day-pass price, 106px tall and
   1073px wide, five times down the section. Nothing else on the site does this;
   measured with und.js, which reports every underlined link over 50px tall. */
body.tb-body .bm-tab a{text-decoration:none;}
/* The colour was caught by the same trap: every page asked for muted grey and
   got the accent purple, so an inactive rail item was as loud as the active
   one. Quiet grey, ink for the current section, and the 2px bar does the rest. */
body.tb-body .cx-rail a:hover,
body.tb-body .bm-rail a:hover,
body.tb-body .pk-rail a:hover,
body.tb-body .bn-rail a:hover,
body.tb-body .mx-rail a:hover,
body.tb-body .vh-rail a:hover,
body.tb-body .cx-rail a[aria-current="true"],
body.tb-body .bm-rail a[aria-current="true"],
body.tb-body .pk-rail a[aria-current="true"],
body.tb-body .bn-rail a[aria-current="true"],
body.tb-body .mx-rail a[aria-current="true"],
body.tb-body .vh-rail a[aria-current="true"]{color:var(--tb-ink);}


/* --- ONE FAMILY, ACTUALLY ENFORCED. Any element without its own font rule was
   falling through to includes/stylesheet.css, which sets Inter on body for the
   personal site. Measured: three business pages were rendering body copy in a
   second typeface. The design system is one family, so body.tb-body now states
   it, and every unstyled descendant inherits it. --- */
body.tb-body{font-family:var(--tb-text);}


/* ==========================================================================
   MOBILE TOUCH TARGETS, 2026-08-28.
   Measured on a real 390x844 viewport: the utility bar controls were 32px
   high, the footer social links 38px, and the skip link 22px. All are real
   controls and all were under the 44px a thumb needs. Raised here rather
   than per page so nothing can drift. Inline links inside a paragraph are
   deliberately left alone: padding them out would break the line box.
   ========================================================================== */
@media (max-width:900px){
  body.tb-body .tb-aud{min-height:44px;display:inline-flex;align-items:center;}
  /* 48 was four pixels of header nobody asked for: the controls inside are
     44px targets, so the bar only ever needed to be 44. */
  body.tb-body .tb-utility-inner{height:auto;min-height:44px;}
  body.tb-body .tb-utility-inner a{min-height:44px;display:inline-flex;align-items:center;}
  body.tb-body footer.ft .ft-social{min-width:44px;min-height:44px;display:inline-flex;
    align-items:center;justify-content:center;}
  body.tb-body .tb-skip{min-height:44px;display:inline-flex;align-items:center;}

  /* The footer navigation columns and contact rows are standalone links, not
     prose, and were 32px and 23px. The footer is SHARED with the personal
     site, so this is scoped to body.tb-body and personal is untouched. */
  body.tb-body footer.ft .ft-list a,
  body.tb-body footer.ft .ft-col a,
  body.tb-body footer.ft .ft-contact-item{
    min-height:44px !important;display:flex !important;align-items:center !important;}
  body.tb-body .tb-burger{min-width:44px;min-height:44px;}

  /* THE PACKAGE BUILDER. This is the page a buyer is most likely to be using
     one-handed on a phone, and every one of its controls was under 44px:
     the quantity steppers at 40, the term pills at 38 and 34, and the info
     buttons at 32. A stepper you miss is a wrong quantity in a quote. */
  body.tb-body .bsp-i{min-width:44px;min-height:44px;}
  body.tb-body .bsp-simterm-btn,
  body.tb-body .bsp-srterm-btn{min-height:44px;}
  body.tb-body .bsp-qty-btn{min-width:44px;min-height:44px;}
  body.tb-body .bsp-qty-val{min-height:44px;}

  /* The consent checkbox on the enquiry form rendered at 19x19. WCAG 2.5.8
     wants 24 minimum and a thumb wants more, and this is the control that
     gates the form submitting at all.
     26 NOT 24, 2026-09-10. 24 is the floor, and a control sitting exactly on
     a floor is the thing you miss twice before you hit it. Two pixels cost
     nothing and this is the last click before an enquiry is sent. */
  body.tb-body input[type=checkbox],
  body.tb-body input[type=radio]{width:26px;height:26px;min-width:26px;min-height:26px;
    accent-color:var(--tb-purple);}

  /* The Cloud PBX industry jump row is a navigation control, not prose. */
  body.tb-body .cx-i-jump-links a{min-height:44px;display:inline-flex;align-items:center;}

  /* THE FLOATING WIDGETS SAT ON TOP OF THE RUNNING TOTAL. Measured at 390px:
     the package builder's fixed total bar occupies y 782 to 844, and the chat
     launcher sits at y 774 to 830 with a z-index of 2,147,483,000. So the most
     important number on the configurator, the price, was underneath a chat
     tease. Both floating widgets are lifted clear of any page that has a fixed
     bottom bar. */
  body.bsp-page .tsc-launch{bottom:82px !important;}
  body.bsp-page{padding-bottom:74px;}

  /* Standalone quiet links are navigation, not prose, so they get a thumb. */
  body.tb-body [class$="-quiet"]{min-height:44px;display:inline-flex;align-items:center;}
}

/* ==========================================================================
   THE DARK BANDS, IN ONE PLACE. 2026-08-28.
   These 42 selectors each used to carry an identical 15-declaration copy of
   the inverse token set, pasted inline. That is the bug factory: update one
   and forget the rest and the failure is silent white-on-white. The tokens
   now live here once. Each rule above still sets only its own background.
   ========================================================================== */
body.bbn-page .bn-h,
body.bbn-page .bn-k,
body.bbn-page .bn-t,
body.bmx-page .mx-h,
body.bmx-page .mx-t,
body.bsim-page .bm-h,
body.bsim-page .bm-f,
body.bsim-page .bm-t,
body.pkt-page .pk-h,
body.pkt-page .pk-t,
body.iotm-page .io-h,
body.iotm-page .io-w,
body.iotm-page .io-t,
body.vph-page .vh-h,
body.vph-page .vh-t,
body.bct-page .ct-n,
body.bfaq-page .fq-h,
body.bfaq-page .fq-e,
body.smx-page .sx-h,
body.smx-page .sx-t,
body.bir-page .br-h,
body.bir-page .br-d,
body.irx-page .ir-d,
body.irx-page .ir-t,
body.brm-page .bm-h,
body.brm-page .bm-eu,
body.brm-page .bm-e,
body.bbs-page .bs-h,
body.bbs-page .bs-c,
body.bsp-page .bsp-bottom,
body.rzn-page .rz-h,
body.rzn-page .rz-e,
body.bbt-page .bt-mast,
body.bc-page .bc-band-h,
body.bc-page .bc-band-t,
body.bck-page .bk-h,
body.bpv-page .bp-h,
body.btm-page .bt-h,
body.wty-page .wt-h,
body.sup-page .sup-t,
body.sup-hub .sup-t,
body.business-landing-page .tbh,
/* THE INVERSE INK RUN. Membership changed 2026-09-02 with the rhythm:
   .tbn LEFT this list - it is now WHITE, and white ink on it would be invisible.
   .tbd JOINED it - it is now the TISA Blue brand moment and needs inverse ink
   (white 10.63 on blue, #E9DCF8 support 8.74, both AA). */
body.business-landing-page .tbd,
body.business-landing-page .tbc,
body.irx-page .ir-h,
body.wty-page .wt-u,
body.business-landing-page .tbt{
    --tb-paper:rgba(255,255,255,0.08);
    --tb-ink:#FFFFFF;
    --tb-body:#E9DCF8;
    --tb-muted:#E9DCF8;
    --tb-accent-text:#FFFFFF;
    --tb-accent-text-hover:#FFFFFF;
    --tb-line:rgba(255,255,255,0.16);
    --tb-line-soft:rgba(255,255,255,0.10);
    --tb-line-strong:rgba(255,255,255,0.22);
    --tb-white:rgba(255,255,255,0.05);
    --tb-zebra:rgba(255,255,255,0.05);
    --tb-purple-soft:rgba(255,255,255,0.06);
    /* THE CTA ON A BLUE GROUND. --tb-purple is the accent FILL and is #081A2B,
       which on a #081A2B section is 1.0:1 - the button would vanish. TISA
       Purple takes it here: white on #9E0493 is 5.58:1, so every existing
       white button label stays correct and no label rule is touched. Hover
       presses into Midnight Ink (white on it, 19.36:1). */
    --tb-purple:#9E0493;
    --tb-purple-deep:#320561;
    --tb-live:#3DDC84;
    --tb-titanium:#E9DCF8;
    color:#E9DCF8;
    /* THE CTA ON A DARK GROUND, 2026-09-01. MEASURED: #6108C0 is 1.60:1 on the
       old #081A2B and 1.58:1 on the new #320561 - the primary action has NEVER
       separated from its own ground on any of the eight pages that put it on a
       dark band, and WCAG 1.4.11 wants 3:1 for a component boundary. A white
       fill is 16.84:1 on #320561 and 18.64:1 on #320561, and it is the classic
       dark-ground primary. This flips the pair for everything inside a dark
       section; no button rule and no markup is touched. */
    --tb-cta-fill:#FFFFFF;
    --tb-cta-fill-hover:#FFFFFF;
    --tb-cta-ink:#320561;
}

/* ============================================================================
   TB-SITE-CTA-V1 - 2026-08-29.
   THE INTERIOR PAGES WERE NOT ON THE HOMEPAGE'S CTA SYSTEM.

   MEASURED across 27 Business pages. "Get a quote" - the same words, the same
   act - rendered as:
       homepage    #6108C0   h52  r8px   15px/600
       broadband   #9E0493   h56  r0px   16px/600
       cloud-pbx   #081A2B   h56  r12px  15px/600
       faqs        #9E0493   h56  r0px   16px/600
       contact     #081A2B   h56  r0px   16px/600
   Three colours, four heights, three radii, two sizes.

   THE CAUSE IS NOT PAGE-BY-PAGE DRIFT. Every one of these buttons is written
   `background:var(--tb-purple)`, and --tb-purple is the accent FILL: #081A2B
   on a light ground, flipped to #9E0493 on a dark one so a filled button is
   not 1.0:1 against a #081A2B section. So one class renders navy in a light
   section and magenta in a dark one ON THE SAME PAGE. The hero answered this
   in writing months ago and only the homepage ever got the answer.

   WHY THIS IS SCOPED TO THE BUTTON CLASSES AND NOT THE TOKEN: re-pointing
   --tb-purple globally would repaint the homepage's "Replace it with Cloud
   PBX", which is deliberately navy, and every other non-button use of the
   token. The homepage uses none of the classes below, so it cannot be
   touched by this block. Personal never loads this stylesheet.
   ========================================================================= */
body.tb-body .bc-go,  body.tb-body .bm-go,  body.tb-body .bn-go,
body.tb-body .br-go,  body.tb-body .bs-go,  body.tb-body .ct-go,
body.tb-body .cx-go,  body.tb-body .fq-go,  body.tb-body .ir-go,
body.tb-body .mx-go,  body.tb-body .pg-go,  body.tb-body .pk-go,
body.tb-body .rz-go,  body.tb-body .sup-go, body.tb-body .sx-go,
body.tb-body .vh-go,  body.tb-body .wt-go,
/* .bsp-selfserve-btn LEFT THIS LIST 2026-09-09. It is the alternative action
   on the quote page and sat beside "Send the enquiry" as a second identical
   filled button, so that section had two primary CTAs and no hierarchy. It is
   styled as the outline secondary in the page CSS instead. Everything else in
   this list is a genuine primary. */
body.tb-body .bsp-btn, body.tb-body .bsp-hero-go{
    background:var(--tb-cta-fill) !important;
    color:var(--tb-cta-ink) !important;
    height:52px !important;
    min-height:52px !important;
    border:0 !important;
    border-radius:var(--tb-r-xs) !important;
    font-family:var(--tb-text) !important;
    font-size:15px !important;
    font-weight:600 !important;
    box-shadow:none !important;
    transition:background 0.22s var(--tb-ease) !important;
}
/* the hero's ruling: a quote button on a telecoms page does not move when a
   cursor passes over it */
body.tb-body .bc-go:hover,  body.tb-body .bm-go:hover,  body.tb-body .bn-go:hover,
body.tb-body .br-go:hover,  body.tb-body .bs-go:hover,  body.tb-body .ct-go:hover,
body.tb-body .cx-go:hover,  body.tb-body .fq-go:hover,  body.tb-body .ir-go:hover,
body.tb-body .mx-go:hover,  body.tb-body .pg-go:hover,  body.tb-body .pk-go:hover,
body.tb-body .rz-go:hover,  body.tb-body .sup-go:hover, body.tb-body .sx-go:hover,
body.tb-body .vh-go:hover,  body.tb-body .wt-go:hover,
body.tb-body .bsp-btn:hover, body.tb-body .bsp-hero-go:hover{
    background:var(--tb-cta-fill-hover) !important;color:var(--tb-cta-ink) !important;
    transform:none !important;box-shadow:none !important;
}

/* THE HEADER LOGO was r9px on all 27 interior pages - the homepage fixed it
   in its own page-scoped block and nothing else inherited that. 9 is not on
   the 8/12/16/24 scale. */
body.tb-body .tb-header .tb-brand img{border-radius:var(--tb-r-xs) !important;}

/* EYEBROW TRACKING. The homepage settled on 0.18em and scoped it to itself;
   the interior pages measured 0.16em (cloud-pbx, contact) and 0.17em
   (support) for the same mark. One value, site-wide on Business. */
body.tb-body [class$="-eyebrow"],
body.tb-body [class$="-eye"]{letter-spacing:0.18em !important;}

/* ---------------------------------------------------------------------------
   FORMS. Measured: contact.php inputs r0px/h50, faqs.php r0px/h56,
   cloud-pbx.php selects r12px/h56 - three radii and two heights for the same
   control, none of them the 8px the buttons beside them use. Radius and focus
   only; sizes, labels, validation and layout are left exactly as they are.
   Checkboxes and radios are excluded: a rounded checkbox is not a checkbox.
   --------------------------------------------------------------------------- */
body.tb-body input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]),
body.tb-body select,
body.tb-body textarea{
    border-radius:var(--tb-r-xs) !important;
    font-family:var(--tb-text) !important;
}
body.tb-body input:not([type=checkbox]):not([type=radio]):focus-visible,
body.tb-body select:focus-visible,
body.tb-body textarea:focus-visible,
body.tb-body input:not([type=checkbox]):not([type=radio]):focus,
body.tb-body select:focus,
body.tb-body textarea:focus{
    outline:2px solid #6108C0 !important;outline-offset:2px !important;
}

/* ==========================================================================
   TB-NO-RISE-ANIM, 2026-09-02.
   Set for exactly one frame by each page's reveal script when the browser has
   restored a scroll position - that is, when the reader has come BACK to this
   page. Everything they are looking at was already read once, so it appears
   instantly instead of fading in a second time. On a fresh load, where scrollY
   is 0, the class is never set and the entrance animation is unchanged.
   ========================================================================== */
html.tb-no-rise-anim [class*="-rise"]{transition:none !important;}

/* ==========================================================================
   THE TWO WIDGETS, PAINTED ONTO THE SYSTEM.  2026-09-03
   The chat bubble carries its own colours inside assets/tisa-chat.js and the
   booking widget paints a few marks from its own component styles, so the
   palette never reaches either through the tokens. The chat launcher was
   still drawing the retired #4A22C4 indigo on EVERY page. Found by walking
   the rendered page for anything computing to an off-palette value, not by
   reading the CSS, which would have missed it: most of this markup only
   exists in the DOM once the widget is opened.
   ========================================================================== */
/* 2026-09-10. THIS BLOCK PAINTED THE ACCENT INK ONTO A DARK GROUND.
   The booking modal is dark (#320561 over a near-black scrim), so #6108C0 ink
   on it measured 1.0-1.6:1 and MEASURED IS THE WORD: the "30 min" and topic
   pills, the required-field asterisks, the booking-summary icons and the
   glyphs inside the topic tiles were all but invisible, on every page,
   in the only booking path the site has. Same lesson as the note below -
   a repaint has to ask what ground the mark sits on, and the answer here is
   dark, so the ink is light. The FILLS below stay purple: they are the marks
   the accent is FOR. */
body.tb-body .bkw-topic-icon,body.tb-body .bkw-required,
body.tb-body .bkw-meta-pill,body.tb-body .bkw-cdr,
body.tb-body .bkw-modal svg{color:#FFFFFF !important;}
body.tb-body .bkw-required{color:#DAD4E6 !important;}
body.tb-body .bkw-host-avatar,body.tb-body .bkw-submit-btn,
body.tb-body .bkw-time-confirm-btn,
body.tb-body .tsc-launch-av,body.tb-body .tsc-head{background:#6108C0 !important;}
/* THE INK WAS NEVER SET WITH THE FILL, and it cost 2026-09-09 a bug report.
   This block repainted .bkw-submit-btn to #6108C0 to get it onto the palette,
   but the widget own rule keeps `color:#320561`, so "Confirm Booking" - the
   final click of the whole booking flow - rendered dark purple on purple at
   **1.73:1**. White on #6108C0 is 9.11, which the note below already says.
   .bkw-time-confirm-btn is added to the fill above for the same reason it is
   added here: it is the SAME action one step earlier, and it was still the
   old white pill, so the two steps did not match.
   IF YOU EVER REPAINT A FILL, SET THE INK IN THE SAME RULE. */
body.tb-body .bkw-submit-btn,
body.tb-body .bkw-time-confirm-btn{color:#FFFFFF !important;}
body.tb-body .bkw-time-confirm-btn:disabled{
    background:rgba(255,255,255,0.20) !important;color:rgba(255,255,255,0.55) !important;}
body.tb-body .tsc-foot a,body.tb-body .tsc-back:hover{color:#6108C0 !important;}
body.tb-body .tsc-chip.tsc-sel{background:#6108C0 !important;border-color:#6108C0 !important;}
body.tb-body .tsc-chip:hover{color:#6108C0 !important;border-color:#6108C0 !important;}
body.tb-body .tsc-form input:focus,body.tb-body .tsc-form textarea:focus{border-color:#6108C0 !important;}
/* THE SEND BUTTON WAS GOLD. assets/tisa-chat.js paints it
   linear-gradient(#FFD700,#F0C000) with #1A1A2E text, so the one action in
   the lead-capture form was in a colour banned brand-wide and in a dark that
   is no longer in the system. The form sits on WHITE, which is where the
   logo indigo works as an action: white on it is 9.11. */
body.tb-body .tsc-send{background:#6108C0 !important;background-image:none !important;
    color:#FFFFFF !important;}
body.tb-body .tsc-send:hover{background:#4C0699 !important;}
body.tb-body .tsc-cont{background:#6108C0 !important;background-image:none !important;
    color:#FFFFFF !important;}
body.tb-body .tsc-chip:hover{background:#F6F3FA !important;}

/* THE TEASER BUBBLE CLIPPED ITS OWN LAST TWO WORDS. assets/tisa-chat.js gives
   .tsc-launch-bubble white-space:nowrap and, when teased, max-width:200px.
   "Need a quote? Chat to us" measures 185px of text plus 28px of padding, so
   it needs 213px and rendered 174px of box: "us" was cut off on every page,
   at every width where the tease fires. Measured, not guessed. The viewport
   term keeps the bubble inside a 320px screen next to the 56px launcher. */
body.tb-body .tsc-launch.tsc-tease .tsc-launch-bubble{
    max-width:min(240px, calc(100vw - 104px)) !important;}

/* THE FLOATING WIDGETS SAT ON TOP OF THE OPEN MOBILE MENU. Measured on
   2026-09-03: the chat launcher is a direct child of body with
   z-index 2147483000, the drawer #tbMobile is z-index 1200, so with the
   full-screen menu open the purple launcher still floated over it, bottom
   right. Seen in a 390 screenshot of the open menu. The "Call Us 4 Free"
   host gets the same treatment for the 768-1060 band, where the burger is
   still shown AND that widget is loaded.
   No JS change is needed: both are body children that come AFTER #tbMobile
   in document order, so a sibling combinator reaches them. display:none on
   the c2c HOST works even though the widget isolates its own inner CSS,
   because the host itself is our element. */
body.tb-body #tbMobile.tb-mobile-open ~ .tsc-launch,
body.tb-body #tbMobile.tb-mobile-open ~ [data-tisa-c2c-host]{display:none !important;}

/* THE SECOND ACTION AT THE END OF A PRODUCT PAGE, 2026-09-03.
   Santosh: "the landing page and product pages at the end must have book a
   meeting button". Every product page already ends with ONE solid action whose
   label belongs to that product (Get a quote, Buy now, Try it now), and those
   are his and stay. This is the outline partner that sits beside it, so the
   section still has one primary.

   MEASURED, not assumed: every closing band renders #320561 with white text on
   all seven pages, even where the class name says -band-w or -band-s, because a
   later rule wins. So border and label are currentColor, which resolves to the
   band's own white and would still be correct if a band ever went light. The
   hover wash is white-on-dark for the same reason.

   Full width below 640 because each page already takes its primary to
   width:100% on a phone, and two half-width buttons on a 320 screen is the
   stacked-price-row fault again. */
/* THE SELECTOR CARRIES body.tb-body AND THE TAG ON PURPOSE, and it is
   load-bearing. Every product page opens its own inline <style> with a reset of
   the form `.bbn-page, .bbn-page *, ... {margin:0;padding:0}`. That is (0,1,1),
   it sits in the page and therefore LATER than this file, so a plain
   `.tb-book-alt` at (0,1,0) lost its padding on all seven pages and the border
   closed up against the label. `body.tb-body a.tb-book-alt` is (0,2,2) and
   wins without needing !important. Verified in CSS.getMatchedStylesForNode,
   not guessed. */
body.tb-body a.tb-book-alt{display:inline-flex;align-items:center;justify-content:center;gap:10px;
    min-height:52px;padding:0 26px;justify-self:start;
    border:1px solid currentColor;border-radius:var(--tb-r-sm);
    background:transparent;color:inherit;
    font-family:var(--tb-text);font-size:16px;font-weight:600;letter-spacing:-0.006em;
    text-decoration:none;white-space:nowrap;
    transition:background .22s var(--tb-ease),transform .22s var(--tb-ease);}
body.tb-body a.tb-book-alt:hover{background:rgba(255,255,255,0.12);color:inherit;transform:translateY(-1px);}
body.tb-body a.tb-book-alt:focus-visible{outline:2px solid currentColor;outline-offset:3px;}
@media (max-width:640px){
    body.tb-body a.tb-book-alt{display:flex;width:100%;margin-left:0;margin-top:12px;}
}

/* SPACING BY CONTAINER TYPE, measured on all seven closing sections.
   Four of them (pocket-office, broadband, bulk-sms, why-tisa) put their
   actions in a FLEX row that already carries a column-gap of 14-34px, so any
   margin here would make the space either side of this button unequal to the
   space around the text link beside it. Two (business-sims, voip-phones) are
   plain BLOCK containers with no gap at all, where two inline-flex buttons
   would otherwise be separated only by the ~4px of collapsed whitespace from
   the newline in the markup. Cloud PBX is a GRID whose children are separate
   rows, so it needs vertical space and NO left margin, or the outline button
   would sit 12px right of the solid button above it.
   justify-self:start above is what stops the grid stretching it to 388px. */
body.bsim-page .bm-t-in > a.tb-book-alt,
body.vph-page .vh-t-in > a.tb-book-alt{margin-left:12px;}
body.cpx-page .cx-t-in > a.tb-book-alt{margin-top:14px;}
@media (max-width:640px){
    body.bsim-page .bm-t-in > a.tb-book-alt,
    body.vph-page .vh-t-in > a.tb-book-alt{margin-left:0;}
}

/* ==========================================================================
   THE BOOK A MEETING BAND, 2026-09-04. Emitted by includes/footer.php on
   every business page that does not already close with a booking section.

   IT IS BUILT MOBILE FIRST, which is the standing rule and also the honest
   order here: on a phone this is a stacked block with a full width button,
   and the two column form only appears at 760 where there is room for it.
   No new colour is introduced - the ground is the same #320561 the footer
   and the hero use, and the button is the white-on-dark pairing the hero
   already ships, measured at 15.9:1.
   ========================================================================== */
body.tb-body .ft-book{background:#320561;color:#FFFFFF;}
body.tb-body .ft-book-in{max-width:var(--tb-max,1240px);margin:0 auto;
    padding:clamp(40px,7vw,64px) var(--tb-pad,24px);
    display:flex;flex-direction:column;gap:clamp(22px,4vw,32px);}
/* The size and measure carry !important ONLY because five support pages ship a
   page level h2 rule that is itself !important, and the shared band must read
   the same on all twenty pages that carry it. Colour and box need no
   !important: body.tb-body outranks a single page class. */
body.tb-body .ft-book h2{font-family:var(--tb-display,"Space Grotesk",sans-serif);
    font-size:clamp(23px,4.4vw,32px) !important;font-weight:600;line-height:1.14;
    letter-spacing:-0.02em;color:#FFFFFF;margin:0 0 10px !important;
    max-width:20ch !important;}
body.tb-body .ft-book p{font-family:var(--tb-text,Inter,sans-serif);font-size:15.5px;
    line-height:1.55;color:#DAD4E6;margin:0 !important;max-width:46ch;}
body.tb-body .ft-book-act{display:flex;flex-direction:column;align-items:flex-start;gap:14px;}
/* 52px, NOT the header's 38: this one has a full row to itself and nothing to
   compete with, so it takes the comfortable touch size rather than the
   compact one. */
body.tb-body .ft-book-btn{display:inline-flex;align-items:center;justify-content:center;
    min-height:52px;padding:0 30px !important;border-radius:var(--tb-r-xs,6px);
    background:#FFFFFF;color:#320561 !important;
    font-family:var(--tb-text,Inter,sans-serif);font-size:16px;font-weight:600;
    text-decoration:none;white-space:nowrap;
    transition:background 0.22s var(--tb-ease,ease),transform 0.22s var(--tb-ease,ease);}
body.tb-body .ft-book-btn:hover{background:#EAE6F1;color:#320561 !important;}
body.tb-body .ft-book-btn:active{transform:translateY(1px);}
body.tb-body .ft-book-alt{font-size:14px !important;color:#DAD4E6 !important;}
/* p.ft-book-alt, not .ft-book-alt: the support pages carry
   .sup-page p a:not([class]) for their own body links, which outranks a two
   class selector and painted this number #6108C0 on #320561, measuring
   1.73:1. Matching on the paragraph as well outranks it without !important. */
body.tb-body .ft-book p.ft-book-alt a{color:#FFFFFF;text-decoration:underline;
    text-decoration-color:rgba(255,255,255,0.55);text-underline-offset:3px;
    /* the whole phone number is a tap target on a phone, so it carries its own
       comfortable hit area rather than relying on the line box */
    display:inline-block;padding:6px 0;}
@media (min-width:480px){
    body.tb-body .ft-book-btn{min-width:210px;}
}
@media (min-width:760px){
    /* The two column form. The copy leads and the action sits at the end of
       the row, aligned to the copy's first line rather than centred, so the
       button lands where the eye already is after reading the heading. */
    body.tb-body .ft-book-in{flex-direction:row;align-items:center;
        justify-content:space-between;gap:clamp(32px,5vw,72px);}
    body.tb-body .ft-book-copy{flex:1 1 auto;min-width:0;}
    body.tb-body .ft-book-act{flex:0 0 auto;align-items:flex-end;}
    body.tb-body .ft-book-alt{text-align:right;}
}

/* ==========================================================================
   READING MEASURE, 2026-09-04.
   Two faults, both measured at 1920 and both invisible to the sweeps because
   nothing overflowed: ledger and list values that carried no max-width at all
   (122ch on the number transfer page, 119 on replacement SIM, 104 on the
   broadband switch note, 98 on the roaming zone list), and legal prose capped
   at 770-792px, which is still 92-99 characters a line at 16px.
   One token, one place. The page level caps are px literals with a single
   class, so body.tb-body plus the page class outranks them without
   !important.
   ========================================================================== */
/* the page class sits ON body, so it is body.tb-body.btm-page and not a
   descendant of it. Getting that wrong is silent: the selector simply never
   matches and the px literal underneath stays in force. */
body.tb-body .sup-led dd,
body.tb-body .su-sub,
body.tb-body .sup-note,
body.tb-body .bc-wrap dl dd,
body.tb-body .bc-note,
body.tb-body .bc-m-lead,
body.tb-body .br-q-list dd,
body.tb-body .br-c-foot,
body.tb-body .br-p-lead,
body.tb-body .br-c-lead,
body.tb-body .br-w-lead,
body.tb-body .ir-c-foot,
body.tb-body .ir-f-lead,
body.tb-body .bm-note,
body.tb-body .rz-inc li,
body.tb-body .rz-z-strap,
body.tb-body .bt-b li,
body.tb-body .bs-f-in p,
body.tb-body .bs-c-in p,
body.tb-body .bs-w-in p,
body.tb-body.btm-page .bt > p,
body.tb-body.bpv-page .bp > p,
body.tb-body.bck-page .bk > p,
body.tb-body.bbt-page .bt-cl > div > p,
body.tb-body.bbt-page .bt-note > p,
body.tb-body.bbt-page .bt-stand{max-width:var(--tb-measure);}

/* The same measure, applied to every prose block the audit at 1920 found
   running past 76 real characters. Enumerated rather than blanket: a bare
   p, li or dd rule would also hit the rows that are flex layouts with a
   figure at the far end, and capping those breaks the row. The list is
   generated from the measurement, not written by hand, so it names what
   actually offended. */
body.tb-body .ob-head > p,
body.tb-body.bbn-page .bn-h-lead,
body.tb-body.bbn-page .bn-k-one > p,
body.tb-body.bbn-page .bn-r-fine,
body.tb-body.bbn-page .bn-w-col > p,
body.tb-body.bbs-page .bs-after,
body.tb-body.bct-page .ct-b-lead,
body.tb-body.bct-page .ct-s-lead,
body.tb-body.bir-page .br-w-body,
body.tb-body.bmx-page .mx-s-inc,
body.tb-body.brm-page .bm-p,
body.tb-body.brm-page .bm-p.is-up,
body.tb-body.bsim-page .bm-b-eu > p,
body.tb-body.bsim-page .bm-b-out,
body.tb-body.bsim-page .bm-d-lead,
body.tb-body.bsim-page .bm-f-quiet,
body.tb-body.bsim-page .bm-p-det > p,
body.tb-body.bsim-page .bm-p-lead,
body.tb-body.bsim-page .bm-p-lp,
body.tb-body.bsp-page .bsp-onuse-l > li,
body.tb-body.bsp-page .bsp-sec-note,
body.tb-body.bsp-page .bsp-sec-note.bsp-sec-facts > li,
body.tb-body.business-landing-page .tbb-offer-sub,
body.tb-body.business-landing-page .tbd-sub,
body.tb-body.business-landing-page .tbq-a,
body.tb-body.cpx-page .cx-b-list > li,
body.tb-body.cpx-page .cx-crm-note,
body.tb-body.cpx-page .cx-f-gnote,
body.tb-body.cpx-page .cx-i-foot,
body.tb-body.cpx-page .cx-p-det > p,
body.tb-body.cpx-page .cx-p-lp,
body.tb-body.cpx-page .cx-s-step > p,
body.tb-body.irx-page .ir-b-lead,
body.tb-body.irx-page .ir-c-lead,
body.tb-body.irx-page .ir-q-item > p,
body.tb-body.pg-page .pg-intro,
body.tb-body.pg-page .pg-mast-lead,
body.tb-body.pg-page .pg-note,
body.tb-body.pg-page .pg-terms li,
body.tb-body.pkt-page .pk-d-body,
body.tb-body.pkt-page .pk-f-note,
body.tb-body.pkt-page .pk-p-det > p,
body.tb-body.pkt-page .pk-p-lead,
body.tb-body.pkt-page .pk-p-lp,
body.tb-body.pkt-page .pk-p-terms,
body.tb-body.smx-page .sx-h-sub,
body.tb-body.smx-page .sx-n-in dd,
body.tb-body.sup-page .sup-flist > li,
body.tb-body.sup-page .sup-p,
body.tb-body.sup-page .sup-p.is-up,
body.tb-body.sup-page .sup-step,
body.tb-body.sup-page .sup-t-lead,
body.tb-body.vph-page .vh-m-diff,
body.tb-body.vph-page .vh-m-lead,
body.tb-body.vph-page .vh-o-note,
body.tb-body.wty-page .wt-p{max-width:var(--tb-measure);}

/* Two ledgers where capping the value left the hairline running most of the
   container on its own. Measured fill of text to rule was 0.59 on the SMS
   ledger and 0.41 on the roaming inclusions list, against 0.74 to 0.97
   everywhere else, which is the device this site already uses. The rule now
   ends with the content it belongs to. The SMS ledger carries a label
   column, so it gets the measure plus that column. */
body.tb-body.smx-page .sx-n-in dl{max-width:calc(var(--tb-measure) + 300px);}
/* The roaming inclusions list is NOT capped here. It reads as a poor fill by
   the same measurement, but it is a two column grid: capping the container
   squeezed both columns to 270px and made it worse. The cap belongs on the
   li, which is where it already is. A fill ratio only means something on a
   single column list. */

/* THE CHAT BUBBLE STANDS DOWN WHILE THE BOOKING MODAL IS OPEN, 2026-09-04.
   On a phone both are anchored bottom right and the chat launcher was drawn
   over the modal, so the customer could tap "chat" while trying to pick a
   time. booking-widget.php puts .bkw-modal-open on <body> when it opens and
   takes it off on every close path (button, overlay click, Escape). The chat
   widget itself is untouched: it is shared with the rest of the site and
   paints itself from assets/tisa-chat.js. */
body.bkw-modal-open .tsc-launch{display:none !important;}

/* ==========================================================================
   THE LARGE-DESKTOP TYPE SCALE, 2026-09-04f.

   THE FAULT, MEASURED. Of 957 fluid values on this site, 853 stop growing at
   or below 1599px and only 10 keep growing past 1920. The scale tokens cap
   between 1379 and 1526, and --fs-lead / --fs-body / --fs-h3 / --fs-ui were
   FIXED PIXELS that never scaled at all. So from about 1680 up, every
   dimension of the page except its side padding was frozen: h1 57px, h2 40px,
   body 19px, section padding 76px, identical on a 1680 laptop and a 2560
   iMac. That is why the site reads as a laptop layout floating in a monitor.

   WHY 1700 AND NOT A LOWER BREAKPOINT. Every value below is continuous with
   the one it replaces AT 1700 - the ramp starts exactly where the old ceiling
   binds, so there is no step at the breakpoint and nothing at or below 1680
   moves by a single pixel. Each then grows to its 2560 value and stops, so an
   ultra-wide screen does not get ever-larger type.
   ========================================================================== */
@media (min-width:1700px){
    :root{
        --fs-display:clamp(68px, calc(36.37px + 1.861vw), 84px);
        --fs-h2:clamp(40px, calc(24.19px + 0.930vw), 48px);
        --fs-h3:clamp(20px, calc(14.07px + 0.349vw), 23px);
        --fs-lead:clamp(19px, calc(13.07px + 0.349vw), 22px);
        --fs-body:clamp(16px, calc(13.04px + 0.174vw), 17.5px);
        --fs-ui:clamp(15px, calc(12.04px + 0.174vw), 16.5px);
        --fs-meta:clamp(13.5px, calc(11.52px + 0.116vw), 14.5px);
        --fs-micro:clamp(11.5px, calc(9.52px + 0.116vw), 12.5px);
        --fs-statement:clamp(29px, calc(19.12px + 0.581vw), 34px);
    }
}

/* ===================================================================
   THE LEGAL DOCUMENT COMPONENT. Added 2026-09-08.

   Three pages are the same kind of object and must not drift apart: the
   business terms, the business privacy policy and the business cookie
   policy. Any page that adds the class "tbdoc" to <body> gets this whole
   system and writes nothing but markup.

   Scoped to .tbdoc. Prefix td-.
   The same document system as broadband-terms.php: one measure, one
   rule weight, a hanging numeral column, quiet tables, print styles.
   =================================================================== */
.tbdoc, .tbdoc *, .tbdoc *::before, .tbdoc *::after{margin:0;padding:0;box-sizing:border-box;}
.tbdoc{background:var(--tb-white);}
.tbdoc h1,.tbdoc h2,.tbdoc h3{font-family:var(--tb-display);font-weight:600;color:var(--tb-ink);letter-spacing:-0.028em;}
.tbdoc p,.tbdoc li,.tbdoc td,.tbdoc th,.tbdoc dt,.tbdoc dd{font-family:var(--tb-text);color:var(--tb-body);}
.tbdoc ul,.tbdoc ol{list-style:none;}
/* ONE UNDERLINE MECHANISM. tb-business.css underlines every link without a
   class with text-decoration and explicitly zeroes any border-bottom, at a
   specificity this page cannot beat with an element selector. Drawing a border
   here as well would have produced the double rule that was cleared off the
   whole site on 2026-09-08, so prose links simply take the shared underline
   and only the navigation and the record line opt out of it below. */
.tbdoc a{color:var(--tb-ink);}
.tbdoc a:hover{color:var(--tb-accent-text);}
.tbdoc a:focus-visible{outline:2px solid var(--tb-purple);outline-offset:3px;}

.tbdoc .td-x{max-width:var(--tb-max);margin:0 auto;padding:0 var(--tb-pad);}

/* --- MASTHEAD. What a reader checks before reading anything. --- */
.tbdoc .td-mast{border-bottom:1px solid var(--tb-ink);}
/* padding-block, NOT the padding shorthand. These three elements carry the
   td-x container class as well, and a shorthand here reset its left and right
   padding to zero, which put the whole document hard against the viewport
   edge at every width. */
.tbdoc .td-mast-in{padding-block:clamp(38px,4.6vw,89px) clamp(26px,3vw,36px);}
.tbdoc .td-kicker{font-family:var(--tb-text);font-size:11.5px;font-weight:700;letter-spacing:0.18em;
  text-transform:uppercase;color:var(--tb-muted);margin-bottom:clamp(16px,2vw,22px);}
.tbdoc .td-mast h1{font-size:clamp(34px,4vw,54px);font-weight:600;line-height:1.01;letter-spacing:-0.038em;max-width:20ch;}
.tbdoc .td-stand{margin-top:clamp(18px,2.2vw,26px);font-size:19px;line-height:1.62;color:var(--tb-body);max-width:64ch;}
.tbdoc .td-rec{margin-top:clamp(24px,3vw,34px);display:flex;flex-wrap:wrap;gap:10px 44px;
  border-top:1px solid var(--tb-line);padding-top:18px;}
.tbdoc .td-rec div{min-width:0;}
.tbdoc .td-rec dt{font-family:var(--tb-text);font-size:11.5px;font-weight:700;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--tb-muted);margin-bottom:5px;}
.tbdoc .td-rec dd{font-family:var(--tb-text);font-size:15px;font-weight:600;color:var(--tb-ink);}
.tbdoc .td-rec dd a{border-bottom-color:var(--tb-muted);}

/* --- THE KEY POINTS. Above the contract, not instead of it. --- */
.tbdoc .td-key{border-bottom:1px solid var(--tb-line);}
.tbdoc .td-key-in{padding-block:clamp(30px,3.4vw,44px);}
.tbdoc .td-key-t{font-family:var(--tb-text);font-size:11.5px;font-weight:700;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--tb-muted);margin-bottom:clamp(16px,2vw,22px);}
.tbdoc .td-key-l{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:clamp(16px,2vw,26px) clamp(28px,4vw,56px);}
.tbdoc .td-key-l div{min-width:0;}
.tbdoc .td-key-l dt{font-family:var(--tb-display);font-size:15px;font-weight:600;color:var(--tb-ink);
  letter-spacing:-0.018em;margin-bottom:4px;}
.tbdoc .td-key-l dd{font-size:14.5px;line-height:1.6;color:var(--tb-body);}
.tbdoc .td-key-l dd a{border-bottom-color:var(--tb-line);}

.tbdoc .td-body{padding-block:clamp(30px,3.6vw,48px) clamp(52px,6vw,88px);
  display:grid;grid-template-columns:238px minmax(0,1fr);gap:0 clamp(34px,5vw,76px);align-items:start;}

/* 112px is the sticky site header, and the offset every other rail on
   the site uses. */
.tbdoc .td-idx{position:sticky;top:112px;max-height:calc(100vh - 138px);overflow-y:auto;}
.tbdoc .td-idx summary{display:none;}
.tbdoc .td-idx-t{font-family:var(--tb-text);font-size:11.5px;font-weight:700;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--tb-muted);padding-bottom:12px;border-bottom:1px solid var(--tb-line);margin-bottom:6px;}
.tbdoc .td-idx-g{font-family:var(--tb-text);font-size:11.5px;font-weight:700;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--tb-accent-text);margin:16px 0 4px;}
.tbdoc .td-idx-g:first-of-type{margin-top:8px;}
.tbdoc .td-idx li a{display:grid;grid-template-columns:26px minmax(0,1fr);gap:8px;
  padding:7px 0;font-family:var(--tb-text);font-size:13.5px;line-height:1.35;color:var(--tb-body);
  border-bottom:0;text-decoration:none;transition:color .18s var(--tb-ease);}
.tbdoc .td-idx li a:hover{color:var(--tb-accent-text);}
.tbdoc .td-idx li a i{font-style:normal;color:var(--tb-muted);font-variant-numeric:tabular-nums;}

.tbdoc .td-stream{border-top:1px solid var(--tb-ink);}
.tbdoc .td-part{padding:clamp(26px,3vw,38px) 0 0;border-bottom:0;}
.tbdoc .td-part p{font-family:var(--tb-text);font-size:11.5px;font-weight:700;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--tb-accent-text);}
.tbdoc .td-cl{display:grid;grid-template-columns:64px minmax(0,1fr);gap:0 clamp(16px,2vw,26px);
  padding:clamp(28px,3.2vw,40px) 0;border-bottom:1px solid var(--tb-line);scroll-margin-top:124px;}
.tbdoc .td-num{font-family:var(--tb-display);font-size:clamp(19px,1.8vw,22px);font-weight:600;
  line-height:1.18;letter-spacing:-0.03em;color:var(--tb-muted);font-variant-numeric:tabular-nums;}
.tbdoc .td-cl h2{font-size:clamp(19px,1.8vw,22px);line-height:1.22;margin-bottom:16px;max-width:30ch;}
.tbdoc .td-cl h3{font-size:15px;font-weight:600;color:var(--tb-ink);letter-spacing:-0.018em;margin:22px 0 8px;}
.tbdoc .td-cl h3:first-of-type{margin-top:0;}
.tbdoc .td-cl p{font-size:16px;line-height:1.72;margin-bottom:13px;max-width:70ch;}
.tbdoc .td-cl p:last-child{margin-bottom:0;}
.tbdoc .td-cl strong{color:var(--tb-ink);font-weight:600;}
.tbdoc .td-cl ul.td-b{margin:0 0 14px;max-width:70ch;}
.tbdoc .td-cl ul.td-b li{font-size:16px;line-height:1.7;padding:5px 0 5px 20px;position:relative;}
.tbdoc .td-cl ul.td-b li::before{content:"";position:absolute;left:2px;top:15px;
  width:6px;height:1px;background:var(--tb-purple);}

/* Definitions read as a list of terms, not as prose. */
.tbdoc .td-def{margin:0;max-width:70ch;}
.tbdoc .td-def div{padding:9px 0;border-bottom:1px solid var(--tb-line);
  display:grid;grid-template-columns:190px minmax(0,1fr);gap:0 22px;}
.tbdoc .td-def div:last-child{border-bottom:0;}
.tbdoc .td-def dt{font-size:15px;font-weight:600;color:var(--tb-ink);}
.tbdoc .td-def dd{font-size:15px;line-height:1.62;}

.tbdoc .td-note{border-left:2px solid var(--tb-purple);padding:2px 0 2px 18px;margin:16px 0;max-width:66ch;}
.tbdoc .td-note p{font-size:15px;line-height:1.66;color:var(--tb-body);margin-bottom:0;}
.tbdoc .td-note strong{color:var(--tb-ink);}
.tbdoc .td-note-key{border-left-color:var(--tb-ink);}

.tbdoc .td-scroll{overflow-x:auto;margin:16px 0 18px;max-width:70ch;}
.tbdoc table.td-t{width:100%;border-collapse:collapse;font-family:var(--tb-text);font-size:15px;}
.tbdoc table.td-t th,.tbdoc table.td-t td{padding:11px 14px 11px 0;text-align:left;
  border-bottom:1px solid var(--tb-line);line-height:1.55;vertical-align:top;font-weight:400;color:var(--tb-body);}
.tbdoc table.td-t thead th{font-size:11.5px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--tb-muted);border-bottom:1px solid var(--tb-ink);padding-bottom:9px;}
.tbdoc table.td-t td.num,.tbdoc table.td-t th.num{text-align:right;padding-right:0;white-space:nowrap;
  font-variant-numeric:tabular-nums;font-weight:600;color:var(--tb-ink);}
.tbdoc table.td-t tr:last-child td,.tbdoc table.td-t tr:last-child th{border-bottom:0;}

.tbdoc .td-unavail{border-left:2px solid var(--tb-ink);padding:2px 0 2px 18px;margin:16px 0;max-width:66ch;}
.tbdoc .td-unavail p{font-size:16px;line-height:1.7;margin-bottom:0;}

.tbdoc .td-foot{margin-top:clamp(28px,3.2vw,40px);font-family:var(--tb-text);font-size:13.5px;
  line-height:1.72;color:var(--tb-muted);max-width:68ch;}
.tbdoc .td-foot a{border-bottom-color:var(--tb-line);}

@media (max-width:1000px){
  /* minmax(0,1fr), NEVER a bare 1fr. A grid item defaults to min-width:auto,
     so a bare 1fr track is floored at the widest child min-content, and a
     wide table put the whole document column at 425px inside a 320px phone.
     html carries overflow-x:hidden site-wide, so nothing scrolled and the
     right hand edge was silently CLIPPED instead. The desktop track above
     already used minmax(0,1fr); these two overrides did not. */
  .tbdoc .td-body{grid-template-columns:minmax(0,1fr);gap:0;}
  .tbdoc .td-idx,.tbdoc .td-stream{min-width:0;}
  .tbdoc .td-idx{position:static;max-height:none;overflow:visible;
    border:1px solid var(--tb-line);border-radius:var(--tb-r-xs);padding:14px 16px;margin-bottom:clamp(26px,3vw,34px);}
  .tbdoc .td-idx summary{display:block;font-family:var(--tb-text);font-size:11.5px;font-weight:700;
    letter-spacing:0.16em;text-transform:uppercase;color:var(--tb-muted);cursor:pointer;list-style:none;}
  .tbdoc .td-idx summary::-webkit-details-marker{display:none;}
  .tbdoc .td-idx-t{display:none;}
  .tbdoc .td-idx ol{margin-top:10px;
    columns:2;column-gap:26px;}
  .tbdoc .td-idx li{break-inside:avoid;}
}
@media (max-width:600px){
  .tbdoc .td-idx ol{columns:1;}
  .tbdoc .td-cl{grid-template-columns:minmax(0,1fr);gap:0;}
  .tbdoc .td-cl > div{min-width:0;}
  .tbdoc .td-num{margin-bottom:6px;font-size:13.5px;letter-spacing:0.14em;}
  .tbdoc .td-def div{grid-template-columns:1fr;gap:3px;}
  .tbdoc table.td-t{font-size:14px;}
  .tbdoc table.td-t th,.tbdoc table.td-t td{padding:9px 10px 9px 0;}
  /* td-t-stack, 2026-09-25. Opt-in, for the only two tables too wide for a phone
     (terms 29, 4 columns; cookies 4, 5 columns). Each row becomes one block: the
     first cell is its heading, every other cell a label/value line from its
     data-label. Every other td-t table is untouched. */
  .tbdoc table.td-t-stack thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
  .tbdoc table.td-t-stack,.tbdoc table.td-t-stack tbody,.tbdoc table.td-t-stack tr{display:block;width:100%;}
  .tbdoc table.td-t-stack tr{padding:12px 0;border-bottom:1px solid var(--tb-line);}
  .tbdoc table.td-t-stack tr:last-child{border-bottom:0;}
  .tbdoc table.td-t-stack td{display:grid;grid-template-columns:minmax(96px,34%) 1fr;gap:12px;padding:3px 0;border:0;text-align:left;white-space:normal;}
  .tbdoc table.td-t-stack td::before{content:attr(data-label);font-size:12px;font-weight:600;letter-spacing:0.02em;color:var(--tb-muted);padding-top:1px;}
  .tbdoc table.td-t-stack td:first-child{display:block;padding:0 0 6px;font-weight:600;color:var(--tb-ink);}
  .tbdoc table.td-t-stack td:first-child::before{content:none;}
  .tbdoc table.td-t-stack td.num{text-align:left;}
}

@media print{
  .tbdoc .td-idx,.tbdoc .td-key{display:none;}
  .tbdoc .td-body{display:block;padding-top:0;}
  .tbdoc .td-cl{break-inside:avoid;}
  .tbdoc a{border-bottom:0;}
}
