/* ==========================================================================
   HostCrafter — the public website.

   Same company as the client area, deliberately not the same rules. The panel
   is somewhere a customer works: flat, quiet, no artwork, because a banner
   between them and their invoice is an obstacle. This is somewhere a stranger
   decides whether to trust us with their website, so it is allowed depth,
   scale, artwork and a hero.

   Colour, 60/30/10. The 30 is #062e79 — the same navy the customer will look
   at every day inside the hosting panel — so the website and the thing it is
   selling are one product rather than two brands that happen to share a name:

     60%  neutral   white surfaces on a faintly blue-tinted canvas
     30%  navy      the hero, the footer, headings, links, the dark bands
     10%  orange    ONE thing: the action you are being asked to take

   Orange is the complement of navy, which is why the buy button is the first
   thing the eye lands on without any element having to shout. Nothing else on
   the page is allowed to be orange. Ticks and confirmations are navy, not
   orange — a tick is not a thing to click, and a page where the ticks and the
   buy button are the same colour is a page with no buy button.

   The logo's own periwinkle stays as `--brand-lite`, used in the mark and in
   artwork. The wordmark is not recoloured to match the site; a logo that
   changes colour with the season is not a logo.

   The illustration palette below is wider — six hues used inside artwork and
   nowhere else. Six brand colours would be no brand at all, but six colours
   inside a drawing of a control panel is just a drawing of a control panel.

   No web fonts. The whole argument of this website is that we are faster than
   whoever the visitor is hosting with now, and a font request that blocks the
   first paint loses that argument before a word is read.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* 30 — the navy from the hosting panel. */
  --brand:      #062e79;
  --brand-2:    #04205a;
  --brand-3:    #031845;
  --brand-soft: #eaf0fa;
  --brand-line: #c3d3ea;
  --brand-tint: #dbe6f6;

  /* The logo's own colour. Artwork and the mark, never a control. */
  --brand-lite: #5262b8;

  /* The dark bands. The panel navy at full strength, and one step deeper for
     the footer, so the two dark ends of the page are not the same flat slab. */
  --ink-deep:   #062e79;
  --ink-deep-2: #041d4f;
  --on-deep:    #b8c8e6;   /* body text on the dark bands — 7.4:1 */
  --on-deep-2:  #8d9fc6;   /* quieter text on the dark bands — 4.7:1 */

  /* 10 — the action.

     Three oranges, because one orange cannot do all three jobs and stay
     readable. --go carries white text at 5.2:1 and is the button. --go-top is
     the lighter end of the button's gradient, still 4.7:1. --go-on-deep is the
     only orange allowed on navy: #f2691c, the panel's own accent, comes to
     4.07:1 there, which is under AA, so text and icons on the dark bands use
     the lighter mix instead. */
  --go:         #c2410c;
  --go-top:     #c94a0d;
  --go-2:       #a5380b;
  --go-on-deep: #f87b33;
  --go-soft:    #fff2e9;
  --go-line:    #f8c7a4;

  /* 60 — neutral. The canvas carries a trace of the brand so that a white
     card on it reads as deliberate rather than as an unstyled div. */
  --surface:   #ffffff;
  --canvas:    #f4f7fc;
  --canvas-2:  #e8eef7;
  --line:      #dfe6f0;
  --line-2:    #c4d0e2;

  --ink:    #0d1a33;
  --ink-2:  #33405c;
  --muted:  #5e6b87;
  --faint:  #8a95ad;

  --warn:      #b54708;
  --warn-soft: #fffaeb;
  --warn-line: #fedf89;

  /* The offer strip. Deep navy rather than orange: orange is now the buy
     button, and a page whose top strip shouts in the same colour as its one
     call to action has two calls to action and therefore none. The strip keeps
     its urgency from the code chip and the link inside it, both orange. */
  --promo:      #041d4f;
  --promo-2:    #072a63;
  --promo-3:    #020f2e;

  --sh-1: 0 1px 2px rgba(6, 46, 121, .06);
  --sh-2: 0 4px 16px rgba(6, 46, 121, .08);
  --sh-3: 0 16px 40px rgba(6, 46, 121, .13);
  --sh-4: 0 28px 64px rgba(4, 29, 79, .22);

  --r-sm: 8px;
  --r:    12px;
  --r-lg: 18px;
  --r-xl: 26px;

  --wrap: 1180px;
  --gut:  clamp(1.1rem, 4vw, 2rem);

  --fast: 120ms cubic-bezier(.4, 0, .2, 1);
  --med:  220ms cubic-bezier(.4, 0, .2, 1);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}


/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* The hidden attribute has to win.

   [hidden] carries the same specificity as a class, and the browser's own
   rule for it is a user-agent rule, so ANY author rule setting display beats
   it — `.hdr-cta { display: flex }` and `.sheet { display: grid }` both did,
   and elements the markup said were hidden rendered anyway. This is the only
   !important in the stylesheet. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anything linked to with a #fragment clears the sticky header. */
  scroll-padding-top: 92px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink-2);
  font-family: var(--font);
  font-size: 16.5px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5 {
  margin: 0 0 .5em;
  color: var(--ink);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.022em;
}
h1 { font-size: clamp(2.1rem, 5.2vw, 3.5rem); letter-spacing: -.032em; }
h2 { font-size: clamp(1.65rem, 3.6vw, 2.5rem); letter-spacing: -.028em; }
h3 { font-size: clamp(1.15rem, 2vw, 1.4rem); }
h4 { font-size: 1.05rem; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--brand); text-decoration: none; transition: color var(--fast); }
a:hover { color: var(--brand-3); }

img, svg { max-width: 100%; }
ul, ol { margin: 0 0 1.1em; padding-left: 1.2em; }

strong, b { font-weight: 650; color: var(--ink); }
small { font-size: .86em; }
code { font-family: var(--mono); font-size: .9em; background: var(--canvas-2); padding: .1em .35em; border-radius: 5px; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

.i { width: 1.25em; height: 1.25em; flex: none; }

/* A logo that is a word rather than a glyph — Woo's, so far. Height is the
   thing to match a square icon on, because a row of icons lines up on its
   optical centre and not on its width. Every place that pins an icon to an
   exact square has to release the width again; there are three of them, and
   they are marked below. */
.i-brand-wide { width: auto; height: .95em; }

/* Present to screen readers, absent from the page. */
.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; top: -100px; left: 1rem; z-index: 200;
  background: var(--go); color: #fff; padding: .6rem 1rem;
  border-radius: 0 0 var(--r-sm) var(--r-sm); font-weight: 600;
}
.skip:focus { top: 0; color: #fff; }

/* --------------------------------------------------------------------------
   3. Layout
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gut);
}
.wrap-narrow { max-width: 820px; }

.section { padding: clamp(3.5rem, 7vw, 6.5rem) 0; }
.section-tight { padding: clamp(2.5rem, 5vw, 4rem) 0; }
.section-canvas { background: var(--canvas); }
.section-line { border-top: 1px solid var(--line); }

/* A dark band. Used for the hero and the closing call to action, and nowhere
   in between — two dark bands in a row read as a template, not a page. */
.section-deep {
  background: var(--ink-deep);
  color: var(--on-deep);
}
.section-deep h1, .section-deep h2, .section-deep h3, .section-deep h4 { color: #fff; }
.section-deep a { color: var(--brand-tint); }

.head {
  max-width: 720px;
  margin: 0 auto clamp(2rem, 4vw, 3.2rem);
  text-align: center;
}
.head-left { margin-inline: 0; text-align: left; }
.head p {
  font-size: 1.1rem;
  color: var(--muted);
  margin-bottom: 0;
}
.section-deep .head p { color: var(--on-deep-2); }

.eyebrow {
  display: inline-block;
  margin-bottom: .8rem;
  color: var(--brand);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.section-deep .eyebrow { color: var(--brand-tint); }

/* Every minmax() floor is wrapped in min(…, 100%).
   `minmax(280px, 1fr)` is a floor the track will not go under even when the
   screen is narrower than 280px, so on a small phone the grid quietly becomes
   wider than the page. min() lets the floor collapse to the container instead. */
.grid { display: grid; gap: 1.25rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .78rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font: inherit;
  font-size: .97rem;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-align: center;
  cursor: pointer;
  transition: background var(--fast), border-color var(--fast),
              color var(--fast), transform var(--fast), box-shadow var(--fast);
}
.btn:active { transform: translateY(1px); }
.btn .i { width: 1.1em; height: 1.1em; }

.btn-primary {
  background: linear-gradient(180deg, var(--go-top), var(--go));
  border-color: var(--go);
  color: #fff;
  box-shadow: 0 1px 2px rgba(13,26,51,.1), 0 6px 18px rgba(194,65,12,.28);
}
.btn-primary:hover {
  background: linear-gradient(180deg, var(--go), var(--go-2));
  border-color: var(--go-2);
  color: #fff;
  box-shadow: 0 2px 4px rgba(13,26,51,.12), 0 10px 26px rgba(194,65,12,.36);
}
.btn-primary:active { box-shadow: 0 1px 2px rgba(13,26,51,.14); }

.btn-deep { background: var(--ink-deep); border-color: var(--ink-deep); color: #fff; }
.btn-deep:hover { background: var(--ink-deep-2); border-color: var(--ink-deep-2); color: #fff; }

.btn-ghost { background: var(--surface); border-color: var(--line-2); color: var(--ink); }
.btn-ghost:hover { background: var(--canvas); border-color: var(--brand-3); color: var(--ink-deep); }

/* On a navy band the ghost button has to invert or it disappears. */
.section-deep .btn-ghost,
.btn-ghost-light {
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.28);
  color: #fff;
}
.section-deep .btn-ghost:hover,
.btn-ghost-light:hover {
  background: rgba(255,255,255,.13);
  border-color: rgba(255,255,255,.5);
  color: #fff;
}

.btn-lg { padding: .95rem 1.9rem; font-size: 1.03rem; }
.btn-sm { padding: .5rem 1rem; font-size: .88rem; }
.btn-block { display: flex; width: 100%; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  align-items: center;
}
.btn-row-center { justify-content: center; }

/* --------------------------------------------------------------------------
   5. Announcement bar
   -------------------------------------------------------------------------- */
/* The offer strip. First thing on the page, and the offer most likely to make
   somebody switch host — so it is set in semibold rather than whispered in grey.

   It is navy, not orange. Orange is the buy button, and a strip shouting in the
   same colour as the one thing you want clicked leaves the page with two calls
   to action and therefore none. What carries the urgency instead is the number
   and the coupon, both of which ARE orange, inside an otherwise dark bar. */
.announce {
  background: linear-gradient(90deg, var(--promo-3), var(--promo) 48%, var(--promo-2));
  color: #fff;
  font-size: .93rem;
  font-weight: 600;
  letter-spacing: -.008em;
  text-align: center;
  padding: .68rem var(--gut);
}
.announce-in {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  flex-wrap: wrap;
}
.announce strong { color: #fff; font-weight: 650; }

/* The number, set large, in a strip that is otherwise small text. Large enough
   to be the first thing read and small enough that it is still a strip and not
   a hero — which is what "large but small text" has to mean at the top of a
   page whose headline is 3.5rem. */
.announce-lead {
  font-size: 1.12em;
  font-weight: 800;
  letter-spacing: -.015em;
  color: var(--go-on-deep);
}
/* ---- the coupon ----------------------------------------------------------
   A code nobody can copy is a code nobody uses. This is set larger than the
   sentence it sits in, drawn as a dashed ticket rather than as more text, and
   `user-select: all` makes one click select the whole of it in every browser
   without a line of JavaScript. site.js layers the clipboard on top and swaps
   in the "Copied" face; the two live in the same box so the chip does not
   change width when it flips. */
.announce-code {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .2rem .7rem;
  border: 1px dashed rgba(248,123,51,.72);
  border-radius: 7px;
  background: rgba(248,123,51,.16);
  color: var(--go-on-deep);
  font: inherit;
  font-family: var(--mono);
  font-size: 1.02rem;
  font-weight: 800;
  letter-spacing: .06em;
  line-height: 1.35;
  cursor: pointer;
  user-select: all;
  -webkit-user-select: all;
  transition: background var(--fast), border-color var(--fast);
}
.announce-code:hover { background: rgba(248,123,51,.28); border-color: var(--go-on-deep); }
.announce-code:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.announce-code-ok {
  position: absolute;
  inset: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .3rem;
  border-radius: 6px;
  background: var(--promo-3);
  font-family: inherit;
  font-size: .84rem;
  letter-spacing: -.01em;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--fast);
}
.announce-code-ok .i { width: 1em; height: 1em; }
.announce-code.is-copied .announce-code-ok { opacity: 1; }
.announce-code.is-copied .announce-code-v { opacity: 0; }

.announce a {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  padding: .12rem .6rem .12rem .7rem;
  border-radius: 999px;
  background: rgba(255,255,255,.16);
  color: #fff;
  font-weight: 650;
  white-space: nowrap;
}
.announce a:hover { background: rgba(255,255,255,.28); color: #fff; }
.announce a .i { width: .95em; height: .95em; transition: transform var(--fast); }
.announce a:hover .i { transform: translateX(2px); }
.announce > .announce-in > .i { width: 1.1em; height: 1.1em; opacity: .85; }

/* On a phone this wrapped to three lines with the icon alone on the first and
   the button alone on the third — 150px of a 844px screen spent before the
   headline. The strip is worth the top of the page; it is not worth the top
   third of it. The leading icon goes (the sentence says "migration" by itself)
   and the link stops being a pill on its own line. */
@media (max-width: 620px) {
  .announce { padding: .55rem var(--gut); font-size: .84rem; line-height: 1.4; }
  .announce > .announce-in > .i { display: none; }
  .announce-lead { font-size: 1.05em; }
  .announce-code { font-size: .92rem; padding: .1rem .5rem; letter-spacing: .05em; }
  .announce-in { gap: .1rem .45rem; }
  .announce a { padding: 0; background: none; text-decoration: underline; text-underline-offset: 2px; }
  .announce a:hover { background: none; }
}

/* --------------------------------------------------------------------------
   6. Header
   -------------------------------------------------------------------------- */
/* Solid, not translucent-with-blur. A backdrop-filter promotes the header to
   its own compositing layer and makes the browser re-blur everything behind it
   on every scroll frame — an odd thing to pay for on a website whose argument
   is that it is faster than the one the visitor is on now. It also renders
   wrong in more than one headless screenshotter. Flat white loses nothing. */
.hdr {
  position: sticky;
  top: 0;
  z-index: 90;
  background: var(--surface);
  border-bottom: 1px solid transparent;
  transition: border-color var(--fast), box-shadow var(--fast);
}
.hdr.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: var(--sh-1);
}
.hdr-in {
  display: flex;
  align-items: center;
  gap: 1.6rem;
  height: 70px;
}

/* The real logo, at its natural aspect. Width and height are on the <img> so
   the header does not reflow when it loads — the logo is above the fold on
   every page and a shifting header is the easiest CLS to avoid. */
.brand { display: inline-flex; align-items: center; flex: none; }
.brand img { display: block; width: auto; height: 38px; }

/* The footer is dark and the wordmark is indigo, so it is lifted to white
   there rather than shipping a second logo file. The mark's own light bars
   survive the filter as greys, which is what the logo does on dark anyway. */
.ftr .brand img { filter: brightness(0) invert(1); opacity: .95; }

.nav { display: flex; align-items: center; gap: .15rem; margin-left: auto; }
.nav a {
  padding: .5rem .8rem;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: .95rem;
  font-weight: 550;
  white-space: nowrap;
}
.nav a:hover { background: var(--canvas); color: var(--ink-deep); }
.nav a.is-on { color: var(--ink-deep); font-weight: 650; }

/* ---- the Pricing dropdown ------------------------------------------------
   Opened on hover on a pointer device and on focus for a keyboard, and the
   parent is a real link to /pricing so a click never dead-ends. There is no
   JavaScript in it: a menu that needs a script to open is a menu that is
   sometimes shut. */
.navdrop { position: relative; }
.navdrop-top { display: inline-flex; align-items: center; gap: .28rem; }
.navdrop-top .i { width: .95em; height: .95em; transition: transform var(--fast); }

.navdrop-menu {
  position: absolute;
  top: 100%;
  left: 50%;
  z-index: 95;
  width: 330px;
  padding: .5rem;
  margin-top: .1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-3);
  /* Moved rather than display:none so it can be animated, and so the gap
     between the link and the panel is still inside the hover target. */
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 6px);
  transition: opacity var(--fast), transform var(--fast), visibility var(--fast);
}
.navdrop:hover .navdrop-menu,
.navdrop:focus-within .navdrop-menu {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}
.navdrop:hover .navdrop-top .i,
.navdrop:focus-within .navdrop-top .i { transform: rotate(180deg); }

.navdrop-menu a {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem .65rem;
  border-radius: var(--r);
  color: var(--ink);
}
.navdrop-menu a:hover, .navdrop-menu a.is-on { background: var(--canvas); }
.navdrop-menu b { display: block; font-size: .95rem; font-weight: 650; letter-spacing: -.012em; }
.navdrop-menu small { display: block; color: var(--muted); font-size: .82rem; line-height: 1.4; }

.navdrop-ico {
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border-radius: 10px;
  flex: none;
}
.navdrop-ico .i { width: 19px; height: 19px; }
.navdrop-ico .i-brand-wide { width: 29px; height: auto; }   /* see .i-brand-wide */
/* Same six tones as the feature cards, and for the same reason — see
   .card-ico-1. The two sets must not drift apart: a visitor sees the dropdown
   and the cards on one screen. */
.navdrop-ico-1 { background: #e6ecfa; color: #3a5bbf; }
.navdrop-ico-2 { background: #dfeaf8; color: #16559e; }
.navdrop-ico-3 { background: #e8eaf7; color: #4a51a8; }
.navdrop-ico-4 { background: #dceefb; color: #0b6bb8; }
.navdrop-ico-5 { background: #e4e9f4; color: #35507f; }
.navdrop-ico-6 { background: #e2e8f8; color: var(--brand); }

.hdr-cta { display: flex; align-items: center; gap: .55rem; flex: none; }
.hdr-cta .btn .i { width: 1em; height: 1em; }

.burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  margin-left: auto;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--ink-deep);
  cursor: pointer;
}

/* Phones only. In the bar there is room for the logo and about three controls,
   so this is the one that goes into the drawer and Log in is the one that
   stays. */
.nav-cta { display: none; }

@media (max-width: 980px) {
  /* The brand pushes everything else right, rather than each control claiming
     the free space with its own auto margin — with two of those the controls
     end up with a gap between them that nothing in the markup asked for. */
  .brand { margin-right: auto; }

  .nav { display: none; }
  .burger { display: inline-flex; margin-left: .2rem; order: 9; }

  /* Signed out, Log in STAYS IN THE BAR. It used to drop into the drawer with
     everything else, which meant signing in on a phone was: tap the burger,
     scroll past four marketing links, tap Log in. People do that on a laptop
     instead, or they do not do it. */
  .hdr-cta { order: 8; gap: .3rem; }
  .hdr-acct { order: 8; }

  /* "Get started" leaves the bar for the drawer — but ONLY where the drawer
     has it. This stylesheet is also loaded by the WHMCS templates, whose header
     is its own markup with no .nav-cta in it, and hiding the button there would
     simply delete the primary call to action from the cart on a phone. */
  .hdr:has(.nav-cta) .hdr-cta .btn-primary { display: none; }

  /* Open state: the nav becomes a sheet under the header rather than a
     full-screen overlay, so the logo and the close control never move. */
  .hdr.is-open .nav {
    display: flex;
    position: absolute;
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: .2rem;
    padding: .8rem var(--gut) 1rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--sh-2);
    max-height: calc(100dvh - 70px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .hdr.is-open .nav { top: 70px; }
  .hdr.is-open .nav > a { padding: .8rem .9rem; font-size: 1.02rem; }

  .hdr.is-open .nav-cta:not([hidden]) {
    display: inline-flex;
    margin-top: .6rem;
    font-size: .98rem;
  }

  /* In the drawer the dropdown is simply open. Hover does not exist here, and
     a tap-to-expand accordion would put the three hosting pages two taps away
     on the device where most of them are read. */
  .navdrop-menu {
    position: static;
    width: auto;
    opacity: 1;
    visibility: visible;
    transform: none;
    margin: 0 0 .4rem;
    padding: .2rem 0 .2rem .55rem;
    border: 0;
    border-left: 2px solid var(--line);
    border-radius: 0;
    box-shadow: none;
  }
  .navdrop-top { padding: .8rem .9rem; font-size: 1.02rem; }
  .navdrop-top .i { display: none; }
}

/* The narrowest phone still in use. Everything above fits at 360px only
   because these four give up a few pixels each: the wordmark loses 4px of
   height, the icon buttons drop from 36 to 32, and "Log in" becomes its key. */
@media (max-width: 420px) {
  .brand img { height: 32px; }
  .hdr-in { gap: .4rem; height: 62px; }
  .hdr.is-open .nav { top: 62px; max-height: calc(100dvh - 62px); }

  .hc-ico { width: 32px; height: 32px; }
  .acct-av { width: 31px; height: 31px; font-size: .72rem; }
  .burger { width: 38px; height: 38px; }

  .hdr-cta .btn-sm { padding-inline: .5rem; }
  .hdr-cta .btn-sm .i { margin: 0; }
  .hdr-cta [data-hc-login] { font-size: 0; gap: 0; }
  .hdr-cta [data-hc-login] .i { width: 17px; height: 17px; }
}

/* --------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  background: var(--ink-deep);
  color: var(--on-deep);
  padding: clamp(3.2rem, 7vw, 5.6rem) 0 clamp(3rem, 6vw, 5rem);
  overflow: hidden;
}
/* Three very soft radial washes. Not a gradient across the whole band — that
   reads as a 2014 template — just enough that the navy is not a flat slab.

   All three are on the brand's own axis: the logo's periwinkle above, a lighter
   blue behind the artwork, and one low, weak ember of the action colour in the
   bottom corner. The violet and teal that used to be here were borrowed from an
   illustration palette and read as a third and fourth brand colour on the one
   screen where the company has to look like one thing. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(56rem 30rem at 80% -14%, rgba(96,124,214,.38), transparent 62%),
    radial-gradient(44rem 26rem at 4% 108%, rgba(194,65,12,.20), transparent 60%),
    radial-gradient(38rem 24rem at 46% 120%, rgba(82,98,184,.34), transparent 66%);
  pointer-events: none;
}
.hero > * { position: relative; }
.hero h1 { color: #fff; margin-bottom: .55rem; }

.hero-lede {
  max-width: 44rem;
  font-size: clamp(1.05rem, 1.9vw, 1.22rem);
  color: var(--on-deep);
  margin-bottom: 1.8rem;
}
.hero-center { text-align: center; }
.hero-center .hero-lede { margin-inline: auto; }

.hero-note {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.4rem;
  margin-top: 1.5rem;
  font-size: .89rem;
  color: var(--on-deep-2);
}
.hero-center .hero-note { justify-content: center; }
.hero-note span { display: inline-flex; align-items: center; gap: .38rem; }
.hero-note .i { width: 1em; height: 1em; color: var(--brand-tint); }

/* --------------------------------------------------------------------------
   8. Trust strip
   -------------------------------------------------------------------------- */
.trust {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px;
  margin-top: clamp(2.2rem, 4vw, 3.2rem);
  background: rgba(255,255,255,.13);
  border: 1px solid rgba(255,255,255,.13);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.trust-item {
  display: flex;
  align-items: center;
  gap: .85rem;
  padding: 1.1rem 1.25rem;
  background: rgba(255,255,255,.045);
}
.trust-item .i { width: 1.5rem; height: 1.5rem; color: var(--brand-tint); flex: none; }
.trust-v { color: #fff; font-size: 1.12rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
.trust-l { font-size: .84rem; color: var(--on-deep-2); }

/* On a light section the same component inverts. */
.trust-light { background: var(--line); border-color: var(--line); }
.trust-light .trust-item { background: var(--surface); }
.trust-light .trust-v { color: var(--ink); }
.trust-light .trust-l { color: var(--muted); }

/* --------------------------------------------------------------------------
   9. Category tabs

   Real links to real pages. They swap the page body in place when JavaScript
   is running, and navigate normally when it is not — so the three keyword
   targets stay three crawlable documents.
   -------------------------------------------------------------------------- */
.tabs {
  display: flex;
  justify-content: center;
  margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
}
.tabs-in {
  display: flex;
  gap: .25rem;
  padding: .3rem;
  background: var(--canvas-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  max-width: 100%;
  /* Without this the max-width above does nothing. A flex item defaults to
     min-width:auto, which is its max-content size, and min-width beats
     max-width — so the pill grew past the screen, and because the body hides
     horizontal overflow the far tab was simply unreachable on a phone. */
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs-in::-webkit-scrollbar { display: none; }

.tab {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .62rem 1.25rem;
  border-radius: 999px;
  color: var(--ink-2);
  font-size: .95rem;
  font-weight: 600;
  white-space: nowrap;
  transition: background var(--fast), color var(--fast), box-shadow var(--fast);
}
.tab:hover { color: var(--ink-deep); }
.tab .i { width: 1.15em; height: 1.15em; }
.tab .i-brand-wide { width: auto; height: .8em; }   /* see .i-brand-wide */
.tab-short { display: none; }
.tab.is-on {
  background: var(--surface);
  color: var(--ink-deep);
  box-shadow: var(--sh-1), 0 0 0 1px var(--line);
}
.tab.is-on .i { color: var(--brand); }

/* The swap. Only the pricing block moves, and only 8px, because the tabs
   themselves must not appear to jump — the eye is anchored on them. */
.swap { transition: opacity 160ms ease, transform 160ms ease; }
.swap.is-out { opacity: 0; transform: translateY(8px); }

/* --------------------------------------------------------------------------
   10. The billing term control
   -------------------------------------------------------------------------- */
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .8rem 1.2rem;
  margin-bottom: clamp(1.8rem, 3vw, 2.6rem);
  max-width: 100%;
}
.controls > * { max-width: 100%; min-width: 0; }

.terms {
  display: inline-flex;
  gap: .2rem;
  padding: .28rem;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  box-shadow: var(--sh-1);
}
.term {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .55rem 1.05rem;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink-2);
  font: inherit;
  font-size: .92rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--fast), color var(--fast);
}
.term:hover { color: var(--ink-deep); }
.term[aria-pressed="true"] { background: var(--ink-deep); color: #fff; }

.term-save {
  padding: .1rem .42rem;
  border-radius: 5px;
  background: var(--go-soft);
  color: var(--go);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: -.01em;
}
.term[aria-pressed="true"] .term-save { background: rgba(248,123,51,.18); color: var(--go-on-deep); }

/* Phones. The term control is the one thing on the page that must never be
   half off-screen — it is what changes the price. So below this width it stops
   being a pill of three buttons and becomes three equal columns across the
   full width, with the saving stacked under the label rather than beside it. */
@media (max-width: 620px) {
  .terms {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    width: 100%;
    min-width: 0;
    border-radius: 14px;
  }
  .term {
    flex-direction: column;
    gap: .12rem;
    padding: .5rem .3rem;
    font-size: .88rem;
    border-radius: 11px;
    text-align: center;
    /* Same min-width:auto trap as the tab strip, one level down: each grid
       item refuses to go under its own min-content width, which pushed the
       three columns wider than the screen and dragged the whole control
       off the left edge. */
    min-width: 0;
  }
  .term > span:first-child { white-space: nowrap; }
  .term-save { font-size: .68rem; padding: .05rem .35rem; }

  /* All three, at once, no scrolling.

     They used to be a pill that scrolled sideways, on the theory that a
     half-visible third tab reads as "there is more this way". It does not: at
     390px the visitor saw WordPress, half of WooCommerce, and no reason to
     believe Agency existed. Three equal columns and the short names fit the
     narrowest phone still in use, and a choice you can see is a choice. */
  .tabs { display: block; }
  .tabs-in {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    width: 100%;
    min-width: 0;
    overflow: visible;
    border-radius: 14px;
    gap: .2rem;
  }
  .tab {
    justify-content: center;
    gap: .38rem;
    padding: .55rem .3rem;
    font-size: .84rem;
    border-radius: 11px;
    min-width: 0;
  }
  .tab .i { width: 1em; height: 1em; }
  .tab .i-brand-wide { height: .7em; }
  .tab-full { display: none; }
  .tab-short { display: inline; }
}

/* Under this the icon and the word cannot share 105px, and the word is the
   half that identifies the tab. */
@media (max-width: 380px) {
  .tabs-in { gap: .15rem; }
  .tab { font-size: .8rem; padding: .55rem .2rem; }
  .tab .i, .tab .i-brand-wide { display: none; }
}

/* --------------------------------------------------------------------------
   11. Plan cards
   -------------------------------------------------------------------------- */
.plans {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  align-items: start;
}
/* Two plans look stranded across a 1180px row. */
.plans-2 { max-width: 780px; margin-inline: auto; }

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.6rem 1.5rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  transition: border-color var(--med), box-shadow var(--med), transform var(--med);
}
.plan:hover {
  border-color: var(--line-2);
  box-shadow: var(--sh-3);
  transform: translateY(-3px);
}
.plan-featured {
  border: 2px solid var(--ink-deep);
  box-shadow: var(--sh-3);
}
.plan-featured:hover { border-color: var(--ink-deep); box-shadow: var(--sh-4); }

.plan-badge {
  position: absolute;
  top: -.72rem;
  left: 50%;
  transform: translateX(-50%);
  padding: .26rem .78rem;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
  box-shadow: 0 4px 12px rgba(82,98,184,.35);
}

.plan-name {
  font-size: 1.28rem;
  font-weight: 750;
  letter-spacing: -.026em;
  color: var(--ink);
  margin: 0;
}
.plan-tag {
  margin: .15rem 0 1.1rem;
  color: var(--muted);
  font-size: .92rem;
  line-height: 1.45;
  min-height: 2.6em;
}

/* ---- the price, boxed -----------------------------------------------------
   Loose on the card this was four lines at four sizes with nothing tying them
   together. On its own tinted ground it is one object: the number is the thing
   the eye lands on, and the strike-through, the saving and the billed total
   are visibly notes about it rather than more card. */
.price-box {
  margin: 0 -.35rem;
  padding: .95rem 1rem .85rem;
  border: 1px solid var(--brand-line);
  border-radius: var(--r);
  background: linear-gradient(180deg, var(--brand-soft), var(--surface) 130%);
}
.plan-featured .price-box {
  border-color: var(--ink-deep);
  background: linear-gradient(180deg, var(--brand-soft), var(--surface) 140%);
}

.price { display: flex; align-items: baseline; gap: .12rem; color: var(--ink); }
.price-sym { font-size: 1.25rem; font-weight: 650; align-self: flex-start; margin-top: .42rem; }
.price-num {
  font-size: clamp(2.5rem, 5vw, 3rem);
  font-weight: 750;
  letter-spacing: -.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.price-frac { font-size: 1.25rem; font-weight: 650; align-self: flex-start; margin-top: .42rem; }
.price-per { margin-left: .3rem; color: var(--muted); font-size: .92rem; font-weight: 500; align-self: flex-end; }

.price-sub {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .45rem;
  margin-top: .5rem;
  font-size: .87rem;
  color: var(--muted);
  min-height: 1.7em;
}
.price-was { text-decoration: line-through; text-decoration-thickness: 1px; color: var(--faint); }
.price-off {
  padding: .08rem .4rem;
  border-radius: 5px;
  background: var(--go-soft);
  border: 1px solid var(--go-line);
  color: var(--go);
  font-size: .76rem;
  font-weight: 700;
}
.price-billed { margin-top: .1rem; font-size: .84rem; color: var(--faint); }

.plan-cta { margin: 1.1rem 0 .2rem; }

/* ---- the region line ------------------------------------------------------
   The first group of the feature list: one ticked line, four flag chips, and
   the chips wrap inside it rather than pushing the line wide. The tick sits on
   the first row of the wrap because .plan-list li aligns to flex-start, which
   is what keeps it reading as one entry in the list and not as a block that
   happens to start with a tick.

   Names, not the three-letter codes this used as a right-aligned spec strip.
   The strip had 120px to work in; the list has the whole card, and "Singapore"
   tells a first-time reader what "SG" does not. */
/* Two by two, not a wrap. Free-flowing, four chips fitted three-then-one on a
   three-up card and four-across on the two-up agency page, so the same fact
   had a different silhouette on every page and the odd one out looked like a
   spill. Fixed columns sized to their content give one block of the same shape
   everywhere, aligned with the ticked lines under it, and it costs no more
   height than the wrap did. */
.plan-regions {
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: .3rem;
}
.rchip {
  display: inline-flex;
  align-items: center;
  gap: .28rem;
  padding: .14rem .42rem .14rem .28rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--canvas);
}
.rchip b {
  color: var(--ink-2);
  font-size: .76rem;
  font-weight: 650;
  letter-spacing: -.008em;
  white-space: nowrap;
}
.rchip .flag { width: 16px; height: 11px; }

/* The flags are drawn 3:2 and must stay 3:2 — a squashed tricolour is worse
   than no flag. The hairline is so a white stripe meeting a white ground still
   has an edge. */
.flag {
  width: 15px;
  height: 10px;
  flex: none;
  border-radius: 1.5px;
  box-shadow: 0 0 0 .5px rgba(23, 27, 52, .18);
}

.plan-list {
  list-style: none;
  margin: 1.1rem 0 0;
  padding: 1.15rem 0 0;
  border-top: 1px solid var(--line);
  display: grid;
  gap: .58rem;
}
.plan-list li {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  font-size: .93rem;
  line-height: 1.45;
  color: var(--ink-2);
}
.plan-list .i {
  width: 1.05em; height: 1.05em;
  margin-top: .28em;
  color: var(--brand);          /* see .ticks .i — never the action colour */
  flex: none;
  stroke-width: 2.6;
}
.plan-list li:first-child { font-weight: 650; color: var(--ink); }

/* ---- the groups -----------------------------------------------------------
   The headings had no rules at all and rendered as body paragraphs, so a card
   read as six unlabelled lists with a stray sentence between them. They are
   set as the section labels they are: small, spaced caps with a rule running
   out to the card edge, which is what makes the groups countable at a glance
   without any of them competing with the price.

   Inside a group the list drops the rule and the top margin it carries when it
   is the card's only list — the heading is the separator now. */
.plan-groups {
  margin-top: 1.15rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 1.15rem;
}
.plan-group-t {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: 0 0 .6rem;
  color: var(--brand-3);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.plan-group-t::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}

.plan-group .plan-list {
  margin: 0;
  padding: 0;
  border-top: 0;
  gap: .48rem;
}

/* A shade heavier than body text. These lines ARE the product — at 400 they
   read as small print under the price, and the reader skims past the thing
   they came to compare. Not bolder than that: eight lines at 650 is a wall. */
.plan-group .plan-list li {
  font-size: .9rem;
  font-weight: 550;
  color: var(--ink-2);
}
/* The flat list bolded its first line. Under headings that would bold the
   first line of all six groups for no reason. */
.plan-group .plan-list li:first-child { font-weight: 550; color: var(--ink-2); }

/* Not on this tier. Greyed, dashed rather than crossed, with the tiers that do
   have it named after it — the line stays where the capability belongs so the
   gap is read against the claim above it, not three groups later. */
.plan-list li.pl-off,
.plan-group .plan-list li.pl-off { color: var(--faint); font-weight: 500; }
.plan-list li.pl-off .i { color: var(--line-2); stroke-width: 3; }
.plan-list li.pl-off em {
  font-style: normal;
  font-size: .86em;
  font-weight: 600;
  color: var(--brand);
  white-space: nowrap;
}
.plan-list li.pl-off em::before { content: '— '; color: var(--line-2); font-weight: 500; }

.plan-note {
  margin-top: 1rem;
  padding: .7rem .85rem;
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  border-radius: var(--r-sm);
  font-size: .84rem;
  line-height: 1.5;
  color: var(--brand-3);
}

.plans-foot {
  margin-top: 1.6rem;
  text-align: center;
  font-size: .92rem;
  color: var(--muted);
}
.plans-foot span { display: inline-flex; align-items: center; gap: .4rem; margin: 0 .7rem; }
.plans-foot .i { width: 1.05em; height: 1.05em; color: var(--brand); }

/* --------------------------------------------------------------------------
   12. Feature cards
   -------------------------------------------------------------------------- */
.card {
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color var(--med), box-shadow var(--med), transform var(--med);
}
.card-hover:hover { border-color: var(--line-2); box-shadow: var(--sh-2); transform: translateY(-2px); }
.card h3 { margin-bottom: .4rem; font-size: 1.09rem; }
.card p { color: var(--muted); font-size: .95rem; margin: 0; }

.card-ico {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  margin-bottom: 1rem;
  border-radius: 11px;
  background: var(--brand-soft);
  color: var(--brand-3);
}
.card-ico .i { width: 22px; height: 22px; }
.card-ico .i-brand-wide { width: 34px; height: auto; }   /* see .i-brand-wide */

/* Six tones, cycled across a row of feature cards, so that nine cards read as
   nine things rather than as one grey wall. The cards are peers: the colour is
   doing the telling-apart and is not saying anything about importance.

   All six sit on the brand's own axis — periwinkle through blue to navy —
   rather than being taken from the illustration palette, which is where they
   used to come from. Teal, violet, amber and rose tiles were four more hues on
   a page that has two, and the eye read them as four more meanings. Value and a
   few degrees of hue separate these enough to tell nine cards apart, and none
   of them can be mistaken for the one orange thing on the page, which is the
   button.

   Every glyph clears 4.6:1 on its own tile. */
.card-ico-1 { background: #e6ecfa; color: #3a5bbf; }
.card-ico-2 { background: #dfeaf8; color: #16559e; }
.card-ico-3 { background: #e8eaf7; color: #4a51a8; }
.card-ico-4 { background: #dceefb; color: #0b6bb8; }
.card-ico-5 { background: #e4e9f4; color: #35507f; }
.card-ico-6 { background: #e2e8f8; color: var(--brand); }

/* The category chooser on the homepage. */
.pick {
  display: flex;
  flex-direction: column;
  padding: 1.7rem 1.6rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  transition: border-color var(--med), box-shadow var(--med), transform var(--med);
}
.pick:hover { border-color: var(--brand-3); box-shadow: var(--sh-3); transform: translateY(-3px); }
.pick h3 { margin-bottom: .3rem; }
.pick p { color: var(--muted); font-size: .95rem; }
.pick-from {
  margin-top: auto;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: .9rem;
  color: var(--muted);
}
.pick-from b { color: var(--ink); font-size: 1.22rem; font-weight: 750; letter-spacing: -.02em; }
.pick-go {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin-top: .7rem;
  color: var(--brand-2);
  font-size: .93rem;
  font-weight: 650;
}
.pick:hover .pick-go .i { transform: translateX(3px); }
.pick-go .i { transition: transform var(--fast); }

/* --------------------------------------------------------------------------
   13. Feature comparison tables
   -------------------------------------------------------------------------- */
/* Six of these stacked open was two and a half screens of numbers. They are
   <details> now, two open and four folded; see pages/hosting.php. Closed, each
   one is a titled bar — so the section still reads as a contents list of
   everything that can be compared, which is the part that was worth the height.
   Open, the ground goes white and the bar keeps its rule, so the header stays
   attached to its own table and not to the next one. */
.ftable {
  margin-bottom: .7rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--canvas);
  overflow: hidden;
  transition: border-color var(--med), background var(--med);
}
.ftable[open] { background: var(--surface); border-color: var(--line-2); box-shadow: var(--sh-1); }
.ftable:last-of-type { margin-bottom: 0; }

.ftable-head {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .85rem 1rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.ftable-head::-webkit-details-marker { display: none; }
.ftable-head:hover { background: var(--canvas-2); }
.ftable[open] .ftable-head { border-bottom: 1px solid var(--line); }
.ftable[open] .ftable-head:hover { background: var(--canvas); }
.ftable-head:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

.ftable-head .i { width: 1.2em; height: 1.2em; color: var(--brand); flex: none; }
.ftable-head h3 { margin: 0; font-size: 1.06rem; }

/* The row count, so a folded table says how much is behind it. */
.ftable-n {
  min-width: 1.55rem;
  padding: .05rem .35rem;
  border-radius: 999px;
  background: var(--canvas-2);
  color: var(--muted);
  font-size: .72rem;
  font-weight: 700;
  text-align: center;
}
.ftable[open] .ftable-n { background: var(--brand-soft); color: var(--brand-3); }

.ftable-head > .i:last-child {
  margin-left: auto;
  color: var(--faint);
  transition: transform var(--med), color var(--fast);
}
.ftable[open] .ftable-head > .i:last-child { transform: rotate(180deg); color: var(--brand); }

.tscroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  -webkit-overflow-scrolling: touch;
}
/* Inside an accordion the panel already draws the box; a second one around the
   table is a double hairline and a rounded corner inside a rounded corner. */
.ftable .tscroll { border: 0; border-radius: 0; }
table.t {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: .93rem;
}
table.t th, table.t td {
  padding: .8rem 1rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
table.t thead th {
  position: sticky;
  top: 0;
  background: var(--canvas);
  color: var(--ink);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
  z-index: 1;
}
table.t tbody tr:last-child th,
table.t tbody tr:last-child td { border-bottom: 0; }
table.t tbody tr:hover td,
table.t tbody tr:hover th { background: var(--canvas); }
table.t tbody th {
  font-weight: 600;
  color: var(--ink);
  width: 34%;
}
table.t td { color: var(--ink-2); }
table.t .num { font-variant-numeric: tabular-nums; white-space: nowrap; }
table.t .yes { color: var(--brand); }
table.t .yes .i { width: 1.15em; height: 1.15em; stroke-width: 2.6; }
table.t .hint {
  display: block;
  margin-top: .12rem;
  font-size: .82rem;
  font-weight: 400;
  color: var(--muted);
}
table.t col.c-us { background: var(--brand-soft); }
table.t thead th.c-us { background: var(--brand-soft); color: var(--brand-3); }

/* On a phone every row becomes a labelled card. A hosting spec table that
   scrolls sideways is a spec table nobody reads. */
@media (max-width: 640px) {
  .tscroll { border: 0; overflow: visible; }
  table.t { min-width: 0; display: block; }
  table.t thead { display: none; }
  table.t tbody, table.t tr, table.t th, table.t td { display: block; width: auto; }
  table.t tbody tr {
    margin-bottom: .7rem;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
    overflow: hidden;
  }
  table.t tbody th {
    width: auto;
    background: var(--canvas);
    border-bottom: 1px solid var(--line);
  }
  table.t td {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .6rem 1rem;
  }
  table.t td::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: .86rem;
    font-weight: 600;
  }
}

/* --------------------------------------------------------------------------
   14. Steps
   -------------------------------------------------------------------------- */
.steps {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  counter-reset: step;
}
.step { position: relative; padding-top: 3.1rem; }
.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  top: 0; left: 0;
  display: grid;
  place-items: center;
  width: 2.3rem; height: 2.3rem;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-size: .98rem;
  font-weight: 700;
}
/* The rule joining the steps. Hidden on the last one and on small screens,
   where the steps stack and a horizontal line would point at nothing. */
.step::after {
  content: "";
  position: absolute;
  top: 1.15rem; left: 2.9rem; right: -1.2rem;
  height: 1px;
  background: linear-gradient(90deg, var(--line-2), var(--line));
}
.step:last-child::after { display: none; }
@media (max-width: 780px) { .step::after { display: none; } }
.step h3 { font-size: 1.08rem; margin-bottom: .3rem; }
.step p { color: var(--muted); font-size: .95rem; margin: 0; }

/* --------------------------------------------------------------------------
   15. FAQ
   -------------------------------------------------------------------------- */
.faq { max-width: 800px; margin-inline: auto; }
.faq details {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  margin-bottom: .65rem;
  transition: border-color var(--fast), box-shadow var(--fast);
}
.faq details[open] { border-color: var(--line-2); box-shadow: var(--sh-1); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem 1.25rem;
  cursor: pointer;
  color: var(--ink);
  font-size: 1.01rem;
  font-weight: 650;
  letter-spacing: -.012em;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .i {
  width: 1.15em; height: 1.15em;
  color: var(--muted);
  flex: none;
  transition: transform var(--med);
}
.faq details[open] summary .i { transform: rotate(180deg); color: var(--brand); }
.faq-body {
  padding: 0 1.25rem 1.15rem;
  color: var(--muted);
  font-size: .96rem;
}
.faq-body p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   16. Prose (written pages: about, terms, privacy)
   -------------------------------------------------------------------------- */
.prose { font-size: 1.03rem; color: var(--ink-2); }
.prose h2 { margin-top: 2.4rem; font-size: 1.6rem; }
.prose h3 { margin-top: 1.8rem; font-size: 1.2rem; }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li { margin-bottom: .45rem; }
.prose a { text-decoration: underline; text-underline-offset: 3px; }
.prose table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; font-size: .95rem; }
.prose th, .prose td { padding: .6rem .8rem; border: 1px solid var(--line); text-align: left; }
.prose th { background: var(--canvas); }

.page-hero {
  padding: clamp(2.5rem, 5vw, 4rem) 0 clamp(1.6rem, 3vw, 2.4rem);
  border-bottom: 1px solid var(--line);
  background: var(--canvas);
}
.page-hero h1 { font-size: clamp(1.9rem, 4vw, 2.8rem); margin-bottom: .3rem; }
.page-hero p { color: var(--muted); font-size: 1.08rem; max-width: 44rem; margin: 0; }

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
  margin-bottom: .8rem;
  font-size: .86rem;
  color: var(--muted);
}
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--ink-deep); }
.crumbs .i { width: .95em; height: .95em; color: var(--faint); }

/* --------------------------------------------------------------------------
   17. Callouts and quotes
   -------------------------------------------------------------------------- */
.note {
  display: flex;
  gap: .85rem;
  padding: 1.1rem 1.25rem;
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  border-radius: var(--r);
  color: var(--brand-3);
  font-size: .96rem;
}
.note .i { width: 1.3em; height: 1.3em; flex: none; margin-top: .15em; }
.note strong { color: var(--ink); }

.note-deep {
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.16);
  color: var(--on-deep);
}
.note-deep strong { color: #fff; }
.note-deep .i { color: var(--brand-tint); }

.quote {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
  font-size: clamp(1.12rem, 2.2vw, 1.42rem);
  line-height: 1.5;
  font-weight: 550;
  letter-spacing: -.02em;
  color: var(--ink);
}
.section-deep .quote { color: #fff; }
.quote-by { margin-top: 1rem; font-size: .92rem; font-weight: 500; color: var(--muted); letter-spacing: 0; }
.section-deep .quote-by { color: var(--on-deep-2); }

/* A row of plain claims with ticks. */
.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.ticks li { display: flex; align-items: flex-start; gap: .6rem; font-size: .98rem; }
/* Ticks are NAVY, not the action colour.

   A plan card carries about forty of them and the comparison tables carry
   hundreds. Painted in the action colour they were forty orange marks
   surrounding one orange button, and the button stopped being the loudest
   thing on the page — which is the only job the action colour has. A tick is
   a confirmation, not something to click. */
.ticks .i { width: 1.1em; height: 1.1em; margin-top: .3em; color: var(--brand); flex: none; stroke-width: 2.6; }
.section-deep .ticks .i { color: var(--brand-tint); }

/* --------------------------------------------------------------------------
   18. Live chat teaser
   -------------------------------------------------------------------------- */
.chatcard {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.4rem;
  padding: 1.5rem 1.7rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
}
.chatcard-ico {
  display: grid;
  place-items: center;
  width: 54px; height: 54px;
  border-radius: 14px;
  background: var(--brand-soft);
  color: var(--brand);
  flex: none;
}
.chatcard-ico .i { width: 26px; height: 26px; }
.chatcard-body { flex: 1 1 260px; }
.chatcard h3 { margin-bottom: .2rem; font-size: 1.12rem; }
.chatcard p { margin: 0; color: var(--muted); font-size: .95rem; }

.online {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .84rem;
  font-weight: 650;
  color: var(--brand);
}
.online::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--go);
  box-shadow: 0 0 0 3px var(--go-soft);
}

/* --------------------------------------------------------------------------
   19. Footer
   -------------------------------------------------------------------------- */
/* One step deeper than the band above it. The call to action immediately
   before the footer is also navy, and at the same value the two ran together
   into one very long dark block with no bottom to the page. */
.ftr {
  background: var(--ink-deep-2);
  color: var(--on-deep-2);
  padding: clamp(3rem, 5vw, 4.5rem) 0 1.6rem;
  font-size: .94rem;
}
.ftr-top {
  display: grid;
  gap: 2.4rem;
  grid-template-columns: minmax(min(240px, 100%), 1.5fr) repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  padding-bottom: 2.4rem;
  border-bottom: 1px solid rgba(255,255,255,.11);
}
/* Below this the four columns cannot coexist at any sensible width, so they
   stack rather than each being squeezed to a two-word wrap. */
@media (max-width: 760px) {
  .ftr-top { grid-template-columns: 1fr; gap: 1.9rem; }
}
.ftr .brand { margin-bottom: 1.1rem; }
.ftr-about { max-width: 34rem; line-height: 1.6; color: var(--on-deep-2); font-size: .92rem; }

.ftr h4 {
  margin-bottom: .9rem;
  color: #fff;
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.ftr ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.ftr a { color: var(--on-deep-2); }
.ftr a:hover { color: #fff; }

.ftr-contact { margin-top: 1.3rem; display: grid; gap: .45rem; font-size: .9rem; }
.ftr-contact span { display: flex; align-items: center; gap: .5rem; }
.ftr-contact .i { width: 1.05em; height: 1.05em; color: var(--brand-tint); flex: none; }

/* ---- currency, in the footer ----------------------------------------------
   A real <select>, so a phone opens the platform's own picker and a keyboard
   gets the platform's own behaviour. The chrome is on the label and the select
   itself is transparent and unpadded, which is the only way to style one of
   these consistently without reimplementing the popup. */
.curpick {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .5rem .3rem .6rem;
  border: 1px solid rgba(185, 192, 228, .22);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .05);
  color: var(--on-deep-2);
  cursor: pointer;
  transition: border-color var(--fast), background var(--fast);
}
.curpick:hover { border-color: rgba(185, 192, 228, .4); background: rgba(255, 255, 255, .09); }
.curpick:focus-within { outline: 2px solid var(--brand-tint); outline-offset: 2px; }
.curpick .i { width: 15px; height: 15px; }

.curpick select {
  border: 0;
  padding: 0 .1rem 0 0;
  background: none;
  color: #fff;
  font: inherit;
  font-size: .86rem;
  font-weight: 600;
  cursor: pointer;
}
/* The list itself is drawn by the OS on a light ground whatever the page is. */
.curpick option { color: var(--ink); background: var(--surface); }

.ftr-bot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .8rem 1rem;
  padding-top: 1.6rem;
  font-size: .87rem;
  color: var(--on-deep-2);
}
/* The copyright takes the slack, so currency and the payment methods sit
   together at the right instead of space-between stranding the currency in the
   middle of the bar with nothing either side of it. */
.ftr-bot > :first-child { margin-right: auto; }
.pay { display: flex; flex-wrap: wrap; gap: .4rem; }
.pay span {
  padding: .22rem .6rem;
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 5px;
  font-size: .76rem;
  letter-spacing: .01em;
}

/* --------------------------------------------------------------------------
   20. Bits
   -------------------------------------------------------------------------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: .38rem;
  padding: .3rem .75rem;
  border-radius: 999px;
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  color: var(--brand-2);
  font-size: .82rem;
  font-weight: 650;
}
.pill .i { width: 1em; height: 1em; }
.pill-light {
  background: rgba(255,255,255,.1);
  border-color: rgba(255,255,255,.2);
  color: #fff;
}
.pill-go { background: var(--go-soft); border-color: var(--go-line); color: var(--go-2); }

.stat-row {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  text-align: center;
}
.stat b {
  display: block;
  font-size: clamp(1.8rem, 4vw, 2.5rem);
  font-weight: 750;
  letter-spacing: -.035em;
  color: var(--ink);
  line-height: 1.1;
}
.section-deep .stat b { color: #fff; }
.stat span { font-size: .9rem; color: var(--muted); }
.section-deep .stat span { color: var(--on-deep-2); }

.hr { height: 1px; background: var(--line); border: 0; margin: 0; }

.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: .6rem; }
.mt-2 { margin-top: 1.2rem; }
.mt-3 { margin-top: 2rem; }
.mt-4 { margin-top: 3rem; }
.mb-0 { margin-bottom: 0; }
.muted { color: var(--muted); }
.small { font-size: .88rem; }

.notfound { padding: clamp(4rem, 10vw, 8rem) 0; text-align: center; }
.notfound .code { font-size: 4rem; font-weight: 750; color: var(--line-2); line-height: 1; }

/* --------------------------------------------------------------------------
   21. Sign-in dropdown

   Hangs off the Log in button. A centred dialog tells somebody they have left
   the page; this tells them to sign in and carry on, which is what they are
   actually doing.
   -------------------------------------------------------------------------- */
.loginwrap { position: relative; }

.loginpop {
  position: absolute;
  top: calc(100% + .55rem);
  right: 0;
  z-index: 120;
  width: 340px;
  padding: 1.15rem 1.15rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-4);
  text-align: left;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--fast), transform var(--fast), visibility var(--fast);
}
.loginwrap.is-open .loginpop { opacity: 1; visibility: visible; transform: none; }

/* The little arrow pointing at the button it belongs to. */
.loginpop::before {
  content: "";
  position: absolute;
  top: -6px; right: 26px;
  width: 11px; height: 11px;
  background: var(--surface);
  border-left: 1px solid var(--line);
  border-top: 1px solid var(--line);
  transform: rotate(45deg);
}

.loginpop-head { margin-bottom: .9rem; }
.loginpop-head b { display: block; font-size: 1.06rem; color: var(--ink); letter-spacing: -.02em; }
.loginpop-head span { font-size: .86rem; color: var(--muted); }

.loginpop-field { display: block; margin-bottom: .7rem; }
.loginpop-field span {
  display: block;
  margin-bottom: .28rem;
  font-size: .85rem;
  font-weight: 620;
  color: var(--ink);
}
.loginpop-field input {
  width: 100%;
  padding: .62rem .75rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .95rem;
  transition: border-color var(--fast), box-shadow var(--fast);
}
.loginpop-field input:focus {
  outline: 0;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

.loginpop-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .8rem;
  margin: .15rem 0 .9rem;
  font-size: .84rem;
}
.loginpop-row label { display: inline-flex; align-items: center; gap: .35rem; color: var(--muted); }

.loginpop-msg {
  margin-bottom: .8rem;
  padding: .55rem .7rem;
  border-radius: var(--r-sm);
  background: #fef3f2;
  border: 1px solid #fecdca;
  color: #b42318;
  font-size: .86rem;
}

.loginpop-alt {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin: .95rem 0 .75rem;
  color: var(--faint);
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.loginpop-alt::before, .loginpop-alt::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.loginpop-social a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .6rem 1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: .93rem;
  font-weight: 600;
}
.loginpop-social a:hover { background: var(--canvas); color: var(--ink); }

/* Google's own button, rendered by its SDK into this slot. Its width is set in
   JavaScript because Google reads it as an attribute rather than from CSS, and
   it renders an iframe that ignores the surrounding rules — so all this does
   is centre it and keep it from overflowing a 320px panel. */
.hc-gbtn {
  display: flex;
  justify-content: center;
  min-height: 40px;
}
.hc-gbtn > div { max-width: 100%; }

/* The neutral half of .loginpop-msg — see finishGoogle() in site.js. */
.loginpop-msg.is-busy {
  background: var(--brand-soft);
  border-color: var(--brand-line);
  color: var(--brand-2);
}

.loginpop-foot {
  margin-top: .95rem;
  padding-top: .85rem;
  border-top: 1px solid var(--line);
  font-size: .85rem;
  color: var(--muted);
}

/* On a phone it becomes a sheet pinned under the header rather than a 340px
   card hanging off a button that is itself near the screen edge. */
@media (max-width: 560px) {
  .loginpop {
    position: fixed;
    top: auto;
    left: .6rem;
    right: .6rem;
    width: auto;
    margin-top: .4rem;
  }
  .loginpop::before { display: none; }
}

/* --------------------------------------------------------------------------
   22. Hero artwork

   One inline SVG, in hero-art.php. It replaced a mockup of the control panel
   built out of thirty empty divs and about 150 lines of CSS — that drawing was
   accurate and it was grey rectangles, which is what every hosting hero looks
   like. Almost nothing is needed here now because the drawing carries its own
   geometry: this file only has to place it, size it and float two pieces of it.
   -------------------------------------------------------------------------- */
.hero-split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 940px) {
  .hero-split { grid-template-columns: 1fr; gap: 2.6rem; }
  .hero-art { order: 2; }
}

.hero-art { position: relative; }

.heroart {
  display: block;
  width: 100%;
  height: auto;
  /* The drawing is drawn to overhang its box on both sides; the hero clips
     horizontal overflow, so this is the whole of the containment. */
  overflow: visible;
}

/* The shadow goes on the one thing that is meant to be lifted off the band, not
   on the whole SVG — on the whole SVG it also shadows the two background washes
   and costs a full-size blur on every paint. */
.heroart-lift { filter: drop-shadow(0 26px 46px rgba(8, 11, 34, .5)); }

/* Three pieces drift, and only three. Everything floating at once is a
   screensaver; the small cards moving against the site card that does not is
   what makes the site read as the solid object in the picture. */
.heroart-float { animation: heroart-float 6s ease-in-out infinite; }
@keyframes heroart-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}
/* Same drift, out of step, so two pieces never rise together. */
.heroart-float-c { animation: heroart-float 7.5s ease-in-out -2.5s infinite; }

/* The WordPress badge carries a translate of its own, so its float has to be
   composed with it rather than replacing it. This keyframe is therefore NOT
   reusable — putting .heroart-float-b on anything else moves that thing 186px
   down the drawing, which is exactly what it did to the traffic card. */
.heroart-float-b { animation: heroart-float-b 7.5s ease-in-out -2.5s infinite; }
@keyframes heroart-float-b {
  0%, 100% { transform: translate(10px, 186px); }
  50%      { transform: translate(10px, 175px); }
}

/* On a phone the drawing sits above the fold with the headline, and at full
   width it pushes the first button off the screen. */
@media (max-width: 560px) {
  .heroart { max-width: 27rem; margin-inline: auto; }
}

/* --------------------------------------------------------------------------
   23. The all-plans page
   -------------------------------------------------------------------------- */
.priceblock { margin-bottom: clamp(3rem, 6vw, 4.5rem); }
.priceblock:last-child { margin-bottom: 0; }

.priceblock-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.4rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--line);
}
.priceblock-head .card-ico { margin: 0; }
.priceblock-head h2 { margin: 0; font-size: clamp(1.3rem, 2.6vw, 1.7rem); }
.priceblock-head p { margin: 0; color: var(--muted); font-size: .93rem; }
.priceblock-head .btn { margin-left: auto; flex: none; }
@media (max-width: 640px) {
  .priceblock-head { flex-wrap: wrap; }
  .priceblock-head .btn { margin-left: 0; width: 100%; }
}

/* The four hero statistics used to take a hue each — violet, teal, sky, amber —
   on the theory that four numbers in one grey row is one number nobody reads.
   On a navy band that put four hues from the illustration palette on the first
   screen of the site, which is the one screen where the company has to look
   like one thing rather than four.

   What separates them now is what was always doing the work: the number is
   white and bold, the label is not, and there is a hairline between the cells.
   The icons are a single quiet tint, because an icon here is a label for a
   number and not a thing competing with it. */
.trust-1 .i,
.trust-2 .i,
.trust-3 .i,
.trust-4 .i { color: var(--brand-tint); opacity: .85; }

/* --------------------------------------------------------------------------
   24. Signed-in header

   The same bar as signed-out, with the two buttons replaced by the things a
   customer actually reaches for: their cart, what they owe, and the way into
   the panel. Deliberately the SAME bar — a customer who signs in should not
   feel they have arrived at a different company's website, which is the whole
   point of the client area sharing this stylesheet.
   -------------------------------------------------------------------------- */
/* Its own display, not .hdr-cta's. The two used to share a class and the
   drawer rules could not tell them apart. */
.hdr-acct {
  display: flex;
  align-items: center;
  gap: .35rem;
  flex: none;
}

/* 36px and 8px radius, which is what .hc-iconbtn measures in the panel. */
.hc-ico {
  position: relative;
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border: 0;
  background: transparent;
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
  transition: background var(--fast), color var(--fast);
}
.hc-ico:hover { background: var(--canvas-2, var(--canvas)); color: var(--ink); }
.hc-ico .i { width: 18px; height: 18px; }

/* The panel's badge: orange, 16px, ringed in the surface colour so it reads as
   sitting on top of the icon rather than beside it. */
.hc-dot {
  position: absolute;
  top: 4px; right: 3px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  border: 2px solid var(--surface);
  background: var(--panel-accent);
  color: #fff;
  font-size: .62rem;
  font-weight: 700;
  line-height: 1;
  display: grid;
  place-items: center;
}
/* Money owed is the one badge allowed to be alarming. */
.hc-dot-due { background: #d92f57; }

/* These four are the PANEL's own colours, copied from hostcrafter.css rather
   than mapped onto this site's emerald. The account bar has to be the same
   object in both halves, and "the same except a different colour" is not the
   same. They are the only place orange appears on this site, which is why they
   are their own tokens and not an addition to the palette. */
:root {
  --panel-accent:      #f2691c;
  --panel-accent-dark: #d45410;
  --panel-accent-soft: #fef2ea;
  --panel-accent-line: #fbcfae;
  --panel-avatar:      #1570ef;
}

/* The bell's list. Same content as the panel's popover, in this side's idiom. */
.bellwrap { position: relative; }

.bellpop {
  position: absolute;
  top: calc(100% + .5rem);
  right: 0;
  z-index: 60;
  width: min(21rem, calc(100vw - 2rem));
  max-height: 22rem;
  overflow-y: auto;
  padding: .35rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-3);
}

.bellpop-row {
  display: block;
  padding: .55rem .6rem .55rem .9rem;
  border-radius: var(--r-sm);
  border-left: 3px solid var(--line-2);
  color: var(--ink-2);
  font-size: .86rem;
  line-height: 1.35;
}
.bellpop-row:hover { background: var(--canvas); color: var(--ink); }
.bellpop-row.is-danger  { border-left-color: #d92f57; }
.bellpop-row.is-warning { border-left-color: var(--warn); }
.bellpop-row.is-success { border-left-color: var(--brand); }
.bellpop-row.is-info    { border-left-color: var(--brand); }

.bellpop-none {
  margin: 0;
  padding: .9rem .6rem;
  color: var(--muted);
  font-size: .86rem;
  text-align: center;
}

.bellpop-all {
  display: block;
  margin-top: .3rem;
  padding: .55rem .6rem;
  border-top: 1px solid var(--line);
  color: var(--brand-2);
  font-size: .84rem;
  font-weight: 600;
  text-align: center;
}
.bellpop-all:hover { background: var(--canvas); color: var(--brand-2); }

/* Signed in, the nav's first item is a button.

   It was `.is-lead` — the same grey link as Support and Billing, a little
   bolder — and a little bolder is not a difference anybody sees. This is the
   destination a signed-in customer came to the site to reach, so it is shaped
   like the thing you press. */
.nav > a.nav-panel-cta {
  margin-right: .5rem;
  padding: .45rem .85rem;
  color: #fff;
  font-weight: 650;
}
.nav > a.nav-panel-cta:hover { color: #fff; background: var(--go-2); }
.nav > a.nav-panel-cta .i { width: 1em; height: 1em; }

.acct { position: relative; }

/* The panel's .hc-avatar-btn: a bare 34px circle, no border, no chevron, and a
   focus ring on open instead of a background change. */
.acct-btn {
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
  border-radius: 50%;
  transition: box-shadow var(--fast);
}
.acct-btn:hover,
.acct-btn[aria-expanded="true"] { box-shadow: 0 0 0 3px rgba(21, 112, 239, .18); }

.acct-av {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--panel-avatar);
  color: #fff;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .01em;
  flex: none;
}

/* The menu still shows the name and email at the top, which is where the panel
   shows them; only the button lost its label. */
.acct-head .acct-av { width: 34px; height: 34px; }
.acct-name {
  max-width: 8.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: .9rem;
  font-weight: 600;
}
@media (max-width: 1080px) { .acct-name { display: none; } }

.acct-menu {
  position: absolute;
  top: calc(100% + .45rem);
  right: 0;
  z-index: 95;
  width: 258px;
  padding: .4rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-3);
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--fast), transform var(--fast), visibility var(--fast);
}
.acct.is-open .acct-menu { opacity: 1; visibility: visible; transform: none; }

.acct-head {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .6rem .6rem .75rem;
  margin-bottom: .3rem;
  border-bottom: 1px solid var(--line);
}
.acct-head b { display: block; font-size: .93rem; color: var(--ink); }
.acct-head small { color: var(--muted); font-size: .8rem; }

.acct-menu a {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem .6rem;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: .93rem;
  font-weight: 550;
}
.acct-menu a:hover { background: var(--canvas); color: var(--brand-2); }
.acct-menu a .i { width: 1.05em; height: 1.05em; color: var(--muted); }
.acct-menu a:hover .i { color: var(--brand); }
.acct-sep { height: 1px; margin: .3rem .3rem; background: var(--line); }
.acct-out { color: #d92f57 !important; }
.acct-out .i { color: #d92f57 !important; }

/* On a phone the account controls stay in the bar rather than dropping into
   the drawer — the cart and the amount owed are why somebody opened the site,
   and they stay put when the menu opens. Only the nav moves. Where they sit and
   what is dropped to make them fit is in the header section with the rest of
   the bar's layout, so there is one place that decides what the bar contains at
   a given width. */
@media (max-width: 980px) {
  .hdr-acct .acct-name { display: none; }

  /* Anchored to the right edge of the bar instead of to a 32px button that is
     itself near the edge, so neither popover can hang off the screen. */
  .bellpop, .acct-menu {
    right: calc(var(--gut) * -1 + .5rem);
    width: min(20rem, calc(100vw - 1.4rem));
  }
}

/* Signed in, "Pricing" has become "Client Area" — a destination rather than a
   category list, so its chevron and its dropdown go with the label. */
.navdrop-top.is-plain .i { display: none; }
.navdrop-top.is-plain ~ .navdrop-menu,
.navdrop:has(.is-plain) .navdrop-menu { display: none; }

/* The cart's slim footer, and the client area's content canvas. Both are used
   only by the WHMCS templates, but they live here because they are made of
   this stylesheet's tokens and would drift if they lived anywhere else. */
.ftr-slim { padding: 1.4rem 0; }
.ftr-slim .ftr-bot { padding-top: 0; border: 0; }

/* --------------------------------------------------------------------------
   25. The dot-grid world map

   A field of ~2,000 dots on a deep indigo band, brightest where we have a
   server and fading with distance from one. The dots are three <path>
   elements, not three thousand <circle> elements: every dot is a zero-length
   subpath and the round stroke cap draws it, which is six bytes a dot and,
   more usefully, three things for the CSS to colour instead of three thousand.

   The colours are not the six illustration hues. On a dark band this map is
   the brand's own indigo pushed up and down in lightness, which is what makes
   two thousand dots read as one object rather than as confetti.
   -------------------------------------------------------------------------- */
.worldsec {
  /* The markers' glow is a box-shadow well outside the map. Without this it
     reaches past the viewport and a phone gets a horizontal scrollbar caused
     by something nobody can see. */
  overflow: hidden;
}

.worldmap {
  position: relative;
  width: 100%;
  max-width: 1000px;
  /* The grid's own aspect ratio, so a marker's percentage position is simply
     its grid coordinate over the grid size. Any other box and the dots and
     their labels would need two different projections. */
  aspect-ratio: 132 / 48;
  margin-inline: auto;
}
.worldmap-svg { display: block; width: 100%; height: 100%; overflow: visible; }

.wdot {
  fill: none;
  stroke-linecap: round;
  stroke-width: .62;
}
.wdot-1 { stroke: #9fbaea; }   /* inside 2,600 km of a location */
.wdot-2 { stroke: #4f6da8; }   /* inside 6,000 km */
.wdot-3 { stroke: #27406f; }   /* everywhere else */

/* ---- a location -----------------------------------------------------------
   The marker is a zero-size point at the projected coordinate and everything
   in it is centred on that point, so the dot sits exactly on the city rather
   than with its top-left corner there. */
.pop {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 0;
  height: 0;
}

.pop-dot, .pop-wave {
  position: absolute;
  top: 0; left: 0;
  width: 14px; height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
}
.pop-dot {
  background: radial-gradient(circle at 38% 32%, #fff, #d3e2f7 42%, #f87b33 100%);
  box-shadow:
    0 0 0 3px rgba(122, 138, 242, .3),
    0 0 16px 4px rgba(122, 138, 242, .55),
    0 0 44px 12px rgba(82, 98, 184, .45);
}

/* One ring leaving the dot every few seconds. Not a loop of three rings: this
   is a map with four of these on it, and twelve simultaneous animations is a
   screensaver. */
.pop-wave {
  border: 1.5px solid rgba(170, 182, 255, .8);
  animation: pop-wave 3.4s cubic-bezier(.2, .6, .3, 1) infinite;
}
@keyframes pop-wave {
  0%        { transform: scale(1);   opacity: .85; }
  70%, 100% { transform: scale(4.8); opacity: 0; }
}
/* Staggered, so the four never pulse in unison and read as one blinking
   object rather than four separate places. */
.pop:nth-of-type(2) .pop-wave { animation-delay: .85s; }
.pop:nth-of-type(3) .pop-wave { animation-delay: 1.7s; }
.pop:nth-of-type(4) .pop-wave { animation-delay: 2.55s; }

/* The label sits on its own ground rather than straight on the dot field.
   Over the Atlantic a bare label is legible and over Europe it is not, and a
   label that is only legible in three of four places is a bug that ships. */
.pop-label {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  padding: .22rem .5rem;
  border: 1px solid rgba(185, 192, 228, .16);
  border-radius: 8px;
  background: rgba(20, 25, 58, .82);
  white-space: nowrap;
  line-height: 1.25;
}
.pop.is-right .pop-label { left: 15px; }
.pop.is-left  .pop-label { right: 15px; text-align: right; }

.pop-label b {
  display: block;
  color: #fff;
  font-size: .84rem;
  font-weight: 650;
  letter-spacing: -.01em;
}
.pop-label i {
  display: block;
  color: var(--on-deep-2);
  font-size: .74rem;
  font-style: normal;
}

/* ---- the same four places, as text ---------------------------------------
   Not a legend for the map — the map is decorative and hidden from screen
   readers, and this is what they read instead. */
.regionlist {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .6rem;
  margin: clamp(1.2rem, 3vw, 2rem) 0 0;
  padding: 0;
  list-style: none;
}
.regionlist li {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .5rem .85rem;
  border: 1px solid rgba(185, 192, 228, .2);
  border-radius: var(--r);
  background: rgba(255, 255, 255, .045);
}
.regionlist-flag { font-size: 1.15rem; line-height: 1; }
.regionlist-t b {
  display: block;
  color: #fff;
  font-size: .9rem;
  font-weight: 600;
}
.regionlist-t small { display: block; color: var(--on-deep-2); font-size: .76rem; }
.regionlist-code {
  padding: .12rem .4rem;
  border-radius: 5px;
  background: rgba(185, 192, 228, .16);
  color: var(--brand-tint);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
}

.worldsec-note {
  max-width: 46rem;
  margin: 1.6rem auto 0;
  color: var(--on-deep-2);
  font-size: .92rem;
  text-align: center;
}

/* A label is 90px wide. Below this the map is under 700px and the four labels
   start to sit on each other, so they go and the list underneath is the map's
   legend — the dots still say "here", which is the part that survives at any
   size. */
@media (max-width: 860px) {
  .pop-label { display: none; }
  .pop-dot, .pop-wave { width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; }
}
@media (max-width: 560px) {
  .regionlist { gap: .45rem; }
  .regionlist li { padding: .45rem .6rem; gap: .5rem; }
  .regionlist-t b { font-size: .84rem; }
}

/* Screen-reader-only text, used by the tick cells in the compare tables. */
.sr-only, .sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

