/* ==========================================================================
   Migration Vision — theme layer: blue, white and yellow (approved 4 Oct 2026)

   Loaded after visual.css on every page. It only overrides: style.css,
   components.css and visual.css are untouched, so removing the <link> to this
   file (THEME_LAYER = False in build_pages.py) restores the previous look.

   Roles
     blue    structure and information: navy grounds, sky glow, blue for links and codes
     white   surfaces: cards, second buttons, breathing room
     yellow  action and highlight: primary buttons, hover, active state, one bold band
   No yellow underlines. Yellow is never text on white; on yellow and on sky
   the text is always navy.

   Changing this file later: run "python theme_layer.py on" (re-stamps the hash on
   the homepage), rebuild, upload css/theme.css FIRST and the pages second. Never
   upload the CSS on its own: it is cached for a month under its ?v= hash.
   ========================================================================== */

/* ---------- tokens: every stray green, teal and electric blue folds into the three ---------- */
:root {
  --yellow: #fdcc32;
  --yellow-dark: #eab512;
  --yellow-pale: #fff0b8;
  --blue-pale: #e3f3fb;
  --blue-text: #1f6f9f;          /* blue that passes 4.5:1 as small text on white and on the pale tints */
  --sun: var(--yellow);
  --green: var(--yellow);        /* decorative dots, borders, gradient ends */
  --green-dark: var(--blue-text);/* coloured text and ticks */
  --cat-study: #2279ab;
  --cat-skilled: #05a2dc;
  --cat-employer: #17223b;
  --cat-family: var(--yellow);
  --cat-other: #5b6f8f;
}
::selection { background: var(--yellow); color: var(--navy-deep); }

/* ---------- buttons ---------- */
.btn-green { background: var(--yellow); color: var(--navy-deep); }
.btn-green:hover {
  background: var(--yellow-dark);
  color: var(--navy-deep);
  box-shadow: 0 8px 20px rgba(253, 204, 50, 0.35);
}
.btn-ghost { background: #fff; border-color: #fff; color: var(--navy-ink); }
.btn-ghost:hover { background: var(--blue-pale); border-color: var(--blue-pale); color: var(--navy-ink); }

/* ---------- keyboard focus ----------
   Links and buttons on light grounds get a blue ring that passes 3:1 (the sky ring did not);
   on navy grounds the sky ring stays. Buttons, pills, tabs and the phone bar get a navy ring
   with a white halo, so it shows on white, on yellow and on navy alike. */
a:focus-visible, button:focus-visible, .consult-card:focus-visible { outline-color: var(--blue-text); }
.topbar a:focus-visible, .ticker a:focus-visible, .hero a:not(.btn):focus-visible,
.page-hero a:not(.btn):focus-visible, .section.navy a:not(.btn):focus-visible,
.aside-card.navy a:not(.btn):focus-visible, .article-cta a:not(.btn):focus-visible,
.blog-featured .feat-art a:focus-visible, .commit-card a:not(.btn):focus-visible,
.modal-close:focus-visible, .footer a:focus-visible { outline-color: var(--sky); }
.mv-mascot:focus-visible { outline-color: var(--navy-deep); }
.cta-band a:not(.btn):focus-visible { outline-color: var(--navy-deep); }
.consult-card:focus-visible { outline: 3px solid var(--blue-text); outline-offset: 2px; }
.btn:focus-visible, .mv-cta-inner a:focus-visible, .visa-tab:focus-visible,
.svc .more:focus-visible, .post-card .more:focus-visible, .ticket-stub .go:focus-visible {
  outline: 3px solid var(--navy-deep);
  outline-offset: 2px;
  border-radius: 999px;
  box-shadow: 0 0 0 8px #fff;
}

/* ---------- "read on" links become small pills: pale blue at rest, yellow on hover ---------- */
.svc .more, .post-card .more, .ticket-stub .go {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--blue-pale);
  color: var(--navy-ink);
  white-space: nowrap;
  transition: background 0.2s ease, transform 0.2s ease;
}
.post-card .more { align-self: flex-start; }
/* the pill must not make the ticket stub taller: the punch-out notches line up with its top edge */
.ticket-stub .go { flex: none; margin-block: -7px; }
.svc .more:hover, .post-card .more:hover, .ticket-stub .go:hover {
  background: var(--yellow);
  color: var(--navy-deep);
  transform: translateX(2px);
}

/* ---------- top bar and navigation ---------- */
.topbar .tb-phone a { color: var(--yellow); font-weight: 700; }
.nav-links a:hover { color: var(--blue-text); }
.drop .code { color: var(--blue-text); }
.scroll-progress { background: var(--yellow); }

/* ---------- blue grounds: sky glow replaces electric blue and teal ---------- */
.hero {
  background:
    radial-gradient(1100px 540px at 85% -10%, rgba(5, 162, 220, 0.3), transparent 60%),
    radial-gradient(800px 500px at -10% 110%, rgba(5, 162, 220, 0.14), transparent 55%),
    linear-gradient(150deg, var(--navy-ink) 0%, var(--navy) 55%, #2c4a78 100%);
}
.hero::after {
  background:
    radial-gradient(520px 320px at 18% 18%, rgba(5, 162, 220, 0.14), transparent 60%),
    radial-gradient(420px 280px at 70% 80%, rgba(5, 162, 220, 0.08), transparent 60%);
}
.page-hero {
  background:
    radial-gradient(900px 420px at 85% -20%, rgba(5, 162, 220, 0.28), transparent 60%),
    linear-gradient(150deg, var(--navy-ink), var(--navy) 70%);
}
.article-cta {
  background:
    radial-gradient(500px 220px at 90% 0%, rgba(5, 162, 220, 0.28), transparent 60%),
    linear-gradient(150deg, var(--navy-ink), var(--navy));
}
.modal-head {
  background:
    radial-gradient(420px 200px at 90% -20%, rgba(5, 162, 220, 0.34), transparent 60%),
    linear-gradient(150deg, var(--navy-ink), var(--navy));
}
.blog-featured .feat-art {
  background:
    radial-gradient(420px 240px at 80% 10%, rgba(5, 162, 220, 0.28), transparent 60%),
    linear-gradient(150deg, var(--navy-ink), var(--navy));
}
#visas.section {
  background:
    radial-gradient(900px 420px at 105% 0%, rgba(5, 162, 220, 0.1), transparent 60%),
    var(--cloud);
}
#team.section {
  background:
    radial-gradient(700px 380px at -5% 0%, rgba(5, 162, 220, 0.09), transparent 55%),
    linear-gradient(180deg, var(--mist-10), #fff);
}

/* ---------- hero details ---------- */
.hero h1 .accent { color: var(--yellow); }
.hero-badge .dot { box-shadow: 0 0 0 4px rgba(253, 204, 50, 0.25); }
.code-chip { color: var(--blue-text); }
.page-hero .code-chip { background: var(--yellow); border-color: var(--yellow); color: var(--navy-deep); font-weight: 600; }

/* ---------- section labels: a yellow dot, not a dash ---------- */
.eyebrow::before, .modal-head .eyebrow::before {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--yellow);
}

/* ---------- stats: navy numbers, blue highlight ---------- */
.stats-band .stat b .u { color: var(--accent-teal-deep); }

/* ---------- trust strip and tick lists alternate blue and yellow ---------- */
.strip .s-item:nth-child(odd) .ico { background: var(--blue-pale); color: var(--blue-text); }
.strip .s-item:nth-child(even) .ico { background: var(--yellow-pale); color: var(--navy-ink); }
.why-list li:nth-child(n) .tick { background: var(--blue-pale); color: var(--blue-text); }
.why-list li:nth-child(2n) .tick { background: var(--yellow-pale); color: var(--navy-ink); }
.reassure .tick { background: rgba(253, 204, 50, 0.18); color: var(--yellow); }
.consent input { accent-color: var(--navy); }
.faq-q::after { color: var(--blue-text); }

/* ---------- visa categories: text stays navy on sky and on yellow ---------- */
.tk[data-cat="skilled"] .tkc, .tk[data-cat="family"] .tkc,
.visa-tab[data-cat="skilled"].active, .visa-tab[data-cat="family"].active { color: var(--navy-deep); }
/* sky and yellow fills are too close to a white tab to mark "selected" on their own */
.visa-tab[data-cat="skilled"].active, .visa-tab[data-cat="family"].active { border-color: var(--navy-deep); }
.visa-tab:not(.active):hover { border-color: var(--blue-text); color: var(--blue-text); }
.ticket[data-cat="skilled"] .code-chip, .ticket[data-cat="family"] .code-chip { color: var(--navy-ink); }
.svc[data-accent="parent"] { --accent: var(--navy); }
/* the 404 page reuses the ticker chips on a white section, where their pale text vanished */
.section .ticker-track .tk, .section .ticker-track .tk:hover { color: var(--navy-ink); background: #fff; border-color: var(--mist-20); }

/* ---------- process steps: blue and yellow in turn ---------- */
.step:nth-child(odd) .node { border-color: var(--blue-soft); }
.step:nth-child(odd) .node svg { stroke: var(--blue-soft); }
.step h3 .n { color: var(--yellow); }

/* ---------- cards ---------- */
.commit-card { border-top: 5px solid var(--yellow); }
.commit-card .stamp path[stroke="#5eead4"] { stroke: var(--yellow); }
.member:nth-child(1) { border-top-color: var(--sky); }
.member:nth-child(2) { border-top-color: var(--yellow); }
.member:nth-child(3) { border-top-color: var(--navy); }
.member .marn-tag { background: var(--blue-pale); border-color: #bfe0f1; }
/* the icon tile hung below the photo, where the photo's own clipping cut it in half */
.svc .svc-photo .svc-ico { bottom: 12px; }
/* booking page: consultation cards */
.consult-card::before { background: var(--sky); }
.consult-cta, .consult-back { color: var(--blue-text); }
.consult-card:hover .consult-cta { color: var(--navy-ink); }
/* links on the navy sidebar card were blue on navy (about 2:1) */
.aside-card.navy a:not(.btn) { color: #fff; text-decoration: underline; }
.aside-card.navy a:not(.btn):hover { color: var(--yellow); }

/* ---------- the one bold yellow moment: the closing call-to-action band ---------- */
.cta-band { background: var(--yellow); color: var(--navy-deep); }
/* the skyline photo stays, washed in yellow instead of electric blue */
.cta-band.has-photo::after { background: linear-gradient(120deg, rgba(253, 204, 50, 0.96), rgba(253, 204, 50, 0.84)); }
.cta-band h2 { color: var(--navy-deep); }
.cta-band p { color: var(--navy-ink); }
.cta-band a:not(.btn), .cta-band a:not(.btn):hover { color: var(--navy-deep); text-decoration: underline; }
.cta-band .btn-green { background: var(--navy-deep); color: #fff; }
.cta-band .btn-green:hover { background: var(--navy); color: #fff; box-shadow: 0 8px 20px rgba(23, 34, 59, 0.3); }
/* the white seal with a mint tick does not read on yellow */
.cta-band .stamp { display: none; }

/* ---------- pledge quote: was navy text on a navy section, so it could not be read ---------- */
.section.navy .pledge p { color: #fff; }
.section.navy .pledge .mark { color: var(--yellow); }
/* !important because the homepage sets this colour in a style attribute (3.8:1 there) */
.section.navy .pledge .by { color: var(--mist) !important; }

/* ---------- footer ---------- */
.footer::before { background: var(--yellow); animation: none; }
.footer a:hover { color: var(--yellow); }
.socials a:hover { background: var(--yellow); color: var(--navy-deep); }

/* ==========================================================================
   Layout faults fixed with this release (not colour changes)
   ========================================================================== */

/* article, contact and booking content ran to the screen edge below 1320 px wide */
.wrap.article-layout, .wrap.contact-page, .wrap.booking-calendar { padding-left: 24px; padding-right: 24px; }

/* in-page links and keyboard focus land below the sticky header, not under it */
html { scroll-padding-top: 100px; }

/* Phones and tablets: pages were wider than the screen, so the browser zoomed them out or
   let them slide sideways. Each cause is fixed below; the clip is the backstop. It sits on
   body only: on html it would stop the enquiry modal locking the page behind it. */
body { overflow-x: clip; }
/* 1. a wide table stretched the whole article column: the column may now shrink */
@media (max-width: 1020px) {
  .article-layout { grid-template-columns: minmax(0, 1fr); }
  .aside { grid-template-columns: minmax(0, 1fr); }
}
.aside-card .facts b { min-width: 0; overflow-wrap: anywhere; }
.article td a { overflow-wrap: anywhere; }
/*    on phones a table still too wide scrolls inside its own box; the soft shadow at an
      edge shows there is more to scroll to */
@media (max-width: 700px) {
  .article table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background:
      linear-gradient(to right, #fff 30%, rgba(255, 255, 255, 0)) left center / 36px 100% no-repeat local,
      linear-gradient(to left, #fff 30%, rgba(255, 255, 255, 0)) right center / 36px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(23, 34, 59, 0.2), transparent) left center / 12px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(23, 34, 59, 0.2), transparent) right center / 12px 100% no-repeat scroll;
  }
}
/* 2. chip rows outside a page hero had no gaps to wrap at */
.hero-codes { display: flex; flex-wrap: wrap; gap: 9px; }
/* 3. the homepage contact card and map ran past the right edge; the email address is kept
      on one line down to 360 px, and wraps below that instead of pushing the card out */
.contact-grid > *, .c-card, .map-frame { min-width: 0; max-width: 100%; }
.c-row > div:last-child { min-width: 0; }
.c-row a, .c-row span.val { overflow-wrap: anywhere; }
@media (max-width: 430px) {
  .ticket-stub .go { padding-left: 10px; padding-right: 10px; }
  .c-card { padding-left: 22px; padding-right: 22px; }
  .c-row { gap: 12px; }
  .c-row a[href^="mailto:"] { font-size: 13.5px; }
}
@media (max-width: 374px) {
  .c-row a[href^="mailto:"] { font-size: 12.5px; }
}

/* Header menu. Inner pages carry eight items, which fit on one line only from about 1180 px.
   Below that the menu button and slide-out panel take over (they used to start at 700 px,
   leaving tablets and small laptops with a menu wrapped over two lines). The .02 keeps a
   zoomed browser at 700.5 or 1180.5 px inside one of the two ranges. */
@media (min-width: 1180.02px) {
  .nav-links > li > a, .nav-cta .btn { white-space: nowrap; }
  /* the sub-menu sat 14 px below its item and closed as the pointer crossed the gap */
  .has-drop::before { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 16px; }
}
@media (min-width: 1180.02px) and (max-width: 1320px) {
  .nav .wrap { gap: 14px; }
  .nav-links { gap: 18px; }
  .nav-links > li > a { font-size: 14px; }
  /* centred on its item, the sub-menu ran past the left screen edge on inner pages */
  .drop { left: 0; transform: translateX(-150px) translateY(8px); }
  .has-drop:hover .drop, .has-drop:focus-within .drop { transform: translateX(-150px) translateY(0); }
}
@media (max-width: 1180px) {
  /* The header's blur made it the frame for the "fixed" panel, so the open menu was a
     136 px box showing one item. Without the blur the panel is fixed to the screen. */
  .nav { backdrop-filter: none; -webkit-backdrop-filter: none; }
  /* inside the panel the sub-menu is a plain list; the desktop hover shift must not apply */
  .has-drop:hover .drop, .has-drop:focus-within .drop { transform: none; }
  /* a closed panel is only slid off-screen: hide it too, or its links stay in the keyboard
     tab order and its shadow shows along the screen edge */
  .nav-links { transition: transform 0.25s ease, visibility 0s linear 0.25s; }
  .nav-links.open { transition: transform 0.25s ease, visibility 0s; }
  .nav-links:not(.open), .nav-links:not(.open) .drop { visibility: hidden; }
  /* the mascot floats above everything; it steps aside while the menu panel is open */
  body:has(.nav-links.open) .mv-mascot { display: none; }
}
@media (min-width: 700.02px) and (max-width: 1180px) {
  .nav-links {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(360px, 85vw);
    background: #fff;
    flex-direction: column;
    align-items: flex-start;
    padding: 96px 30px 40px;
    gap: 20px;
    box-shadow: var(--shadow-lg);
    transform: translateX(100%);
    overflow-y: auto;
    z-index: 70;
  }
  .nav-links.open { transform: translateX(0); }
  .nav-toggle { display: flex; z-index: 80; }
  .nav-toggle.open span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
  .nav-toggle.open span:nth-child(2) { opacity: 0; }
  .nav-toggle.open span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }
  .drop {
    position: static;
    transform: none;
    opacity: 1;
    box-shadow: none;
    border: 0;
    padding: 4px 0 0 8px;
    grid-template-columns: 1fr;
    max-height: none;
    overflow-y: visible;
  }
  .nav-links.open .drop { visibility: visible; }
}

/* ---------- phone: Call and Book always within thumb reach ----------
   .mv-cta-bar is an in-flow spacer at the end of the page; .mv-cta-inner is the fixed bar.
   The spacer keeps the last lines of the footer clear of the bar on pages that have one. */
.mv-cta-bar { display: none; }
@media (max-width: 700px) {
  html { scroll-padding-top: 84px; }
  .mv-cta-bar { display: block; height: calc(69px + env(safe-area-inset-bottom)); background: #fff; }
  .mv-cta-inner {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 50;
    display: flex;
    gap: 10px;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    background: #fff;
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 20px rgba(11, 25, 45, 0.12);
  }
  .mv-cta-inner a {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    border: 2px solid transparent;  /* keeps an edge in forced-colours mode */
    border-radius: 999px;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 15px;
    color: var(--navy-deep);
    white-space: nowrap;
  }
  .mv-cta-inner .mv-cta-call { border-color: var(--navy); background: #fff; }
  .mv-cta-inner .mv-cta-book { background: var(--yellow); }
  /* with the menu open the panel covers most of the bar; hide the rest so a stray tap cannot dial */
  body:has(.nav-links.open) .mv-cta-inner { display: none; }
  /* the mascot sat off-screen on phones before the width fix; beside the bar it would cover buttons */
  .mv-mascot { display: none; }
}
/* keyboard focus and in-page links stop above the bar instead of underneath it */
@media (max-width: 700px) and (min-height: 430.02px) {
  html { scroll-padding-bottom: 88px; }
}
/* very narrow screens: keep both labels inside the screen */
@media (max-width: 340px) {
  .mv-cta-inner { gap: 6px; padding-left: 8px; padding-right: 8px; }
  .mv-cta-inner a { font-size: 13px; }
}
/* very short screens (a phone on its side, or a page zoomed to 400%): the bar would take
   too much of the view, so it steps aside */
@media (max-width: 700px) and (max-height: 430px) {
  .mv-cta-bar { display: none; }
}
