/* LTP overlay on the shared Robocode brand system.
   Loads AFTER robocode-brand.css on every page. Two jobs:
   1. The LTP voice: plum (#5F003E, the booklet's pink-950) as the dark
      surface colour where camps/partners use plain ink, so this site reads
      as the Luminary Tech Path and not a camps clone.
   2. LTP-only components the shared sheet has no equivalent for: the canon
      three-plan pricing cards and the sticky mobile CTA.
   Pink stays the pay action; teal keeps badges, steps, figures and chrome. */

:root {
  --ltp-plum:      #5f003e;   /* --color-pink-950 */
  --ltp-plum-mid:  #98036c;   /* --color-pink-900 */
  --ltp-plum-deep: #3c0028;
  --ltp-navy:      #1e2a4a;   /* the canon pricing-card monthly head */
}

/* ---- hidden means hidden ----------------------------------------------------
   The user agent's [hidden] rule is the weakest thing in the cascade: any
   author rule that sets display beats it. .deadline-strip sets display:block,
   so the late strip carried hidden and rendered anyway - it stayed off screen
   only because site.js removes the expired one from the DOM, which means the
   day site.js fails to load, both deadline banners stack on top of each other.
   .watch-overlay[hidden] was already patched by hand for exactly this. One
   rule for the whole sheet instead, so the next component that sets display
   does not have to remember.                                                  */
[hidden] { display: none !important; }

/* ---- Type law --------------------------------------------------------------
   AIR FORCE appears ONCE per page, on the hero heading, and nowhere else.
   Section headings are the body face, uppercase, so the page still reads as
   the same family without spending the display face on every band. */
.section-h2, .statement-h2 {
  font-family: var(--font-body);
  font-weight: 700;
  letter-spacing: 0.01em;
  font-size: 1.625rem;
}
@media (min-width: 768px) { .section-h2, .statement-h2 { font-size: 2rem; } }
@media (max-width: 599px) { .section-h2, .statement-h2 { font-size: 1.375rem; } }

/* ---- Trust strip: the figure first, its meaning under it ------------------- */
.trust-item {
  flex-direction: column; align-items: center; text-align: center; gap: 0.15rem;
  max-width: 9rem;
}
.trust-item .trust-num { font-size: 1.75rem; line-height: 1.1; }
.trust-item .trust-label { line-height: 1.3; }
.trust-divider { height: 3rem; }

/* ---- Card hover tints ------------------------------------------------------
   A grid of cards in one flat colour reads as a spreadsheet. Each card takes
   its own tint on hover so the grid feels alive under the cursor. */
.card.tint-cyan:hover   { background: var(--color-cyan-50);   border-color: rgba(0,220,222,0.45); }
.card.tint-pink:hover   { background: var(--color-pink-50);   border-color: rgba(255,88,234,0.45); }
.card.tint-orange:hover { background: var(--color-orange-50); border-color: rgba(255,151,82,0.5); }
.card.tint-plum:hover   { background: #fdf1f8;                border-color: rgba(152,3,108,0.35); }

/* ---- Subject cards: the awarding body's own mark, quietly ------------------ */
.subject-card { position: relative; }
.subject-card .board-mark {
  position: absolute; top: 1.1rem; right: 1.1rem;
  height: 1.25rem; width: auto; max-width: 4rem; object-fit: contain;
  filter: grayscale(1); opacity: 0.45; transition: filter 0.2s ease, opacity 0.2s ease;
}
.subject-card:hover .board-mark { filter: none; opacity: 1; }

/* ---- Numbered steps with an icon beside the numeral ----------------------- */
.step-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: 0.625rem; flex-shrink: 0;
  background: var(--color-cyan-50); color: var(--color-cyan-800);
  box-shadow: inset 0 0 0 1px rgba(0,105,112,0.16);
}
.step-icon svg { width: 1.125rem; height: 1.125rem; display: block; }
.steps-tight { gap: 1.25rem; }
.steps-tight .step { padding-left: 3.25rem; display: flex; gap: 0.875rem; align-items: flex-start; }
.steps-tight .step p { margin: 0; }

/* ---- Term dates -------------------------------------------------------------
   Three terms, three cards, one layout at every width. A school calendar is a
   list of labelled dates rather than a grid, so it is set as a definition list:
   the label sits quietly on the left and the date carries the weight. Three of
   anything fits a phone stacked and a desktop in a row, which is why there is
   no second copy of these dates for narrow screens. */
.term-grid { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 900px) { .term-grid { grid-template-columns: repeat(3, 1fr); } }
.term-card { display: flex; flex-direction: column; }
/* A column flex container stretches its children, which turns the badge pill
   into a full-width bar. It should hug its two words like every other badge
   on the page. */
.term-card .robo-badge { align-self: flex-start; }
/* Rows are separated by their own padding and a hairline, not by a row gap:
   a gap leaves the divider floating between entries instead of joining them. */
.term-list { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 0 1.25rem; }
.term-list dt {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--color-muted); white-space: nowrap; padding-block: 0.6rem;
}
.term-list dd { margin: 0; font-weight: 600; color: var(--color-dark); padding-block: 0.6rem; }
/* On a phone the two columns leave the date about 160px, which breaks
   "Monday 26 to Friday 30 October" across three cramped lines. Stack the
   label above the date instead and each entry gets the full width. */
@media (max-width: 560px) {
  .term-list { grid-template-columns: 1fr; gap: 0; }
  .term-list dt { padding-top: 0.85rem; }
  .term-list dt:first-of-type { padding-top: 0; }
  .term-list dd { margin-top: 0.15rem; }
}
.term-aside { display: block; font-weight: 500; color: var(--color-muted); font-size: 0.875rem; }
/* The two weeks we do not follow the school calendar. Amber because it is the
   thing a parent planning a holiday most needs to catch. */
.term-note {
  margin: 1rem 0 0; padding: 0.7rem 0.85rem; border-radius: 0.6rem;
  background: var(--color-amber-100); color: var(--color-amber-700);
  font-size: 0.875rem; line-height: 1.45;
}
.term-card .term-note { margin-top: auto; }

/* ---- Plum dark bands -------------------------------------------------------
   The camps page punctuates with bg-ink; LTP punctuates with plum. Text and
   blob treatments mirror .band-ink / .backdrop-vibrant so the recipe is the
   same system in the LTP colour. */
.band-plum { background: var(--ltp-plum-deep); color: rgba(255,255,255,0.72); }
.band-plum .section-h2, .band-plum .statement-h2, .band-plum h2, .band-plum h3 { color: #fff; }
.band-plum .robo-badge { background: rgba(255,255,255,0.08); color: #ffc6fa; box-shadow: inset 0 0 0 1px rgba(255,152,244,0.25); }
/* A card on a plum band is its own light surface, so the band's light text
   has to stop at its edge. It did not, and the first three cards ever put on
   this band rendered white on white: the headings showed and every word of
   the body was invisible. Same for the badge, which the band tints for a dark
   background and which washed out to nothing on white. */
.band-plum .card { color: var(--color-ink); }
.band-plum .card .robo-badge {
  background-color: var(--color-cyan-50); color: var(--color-cyan-900); box-shadow: none;
}
/* The band sets light text, but any class carrying its own dark colour keeps
   it and inheritance never gets a look in. .lead on this band measured 1.45:1
   against the plum, where body text needs 4.5:1. Cards are excluded because
   they are a light surface of their own. */
.band-plum .lead, .band-plum .muted, .band-plum .p2 { color: rgba(255,255,255,0.82); }
.band-plum .card .lead, .band-plum .card .p2 { color: var(--color-ink); }
.band-plum .card .muted { color: var(--color-muted); }

.backdrop-plum { background: var(--ltp-plum-deep); }
.backdrop-plum::before {
  opacity: 0.07;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 64' width='56' height='64'><path d='M28 4 L52 18 L52 46 L28 60 L4 46 L4 18 Z' fill='none' stroke='%23ffffff' stroke-width='1'/></svg>");
}
.backdrop-plum .blob-a { top: -15%; left: -10%; width: 55vw; height: 55vw; opacity: 0.55; background: radial-gradient(circle, #00dcde 0%, transparent 65%); filter: blur(75px); animation: blobA 22s ease-in-out infinite; }
.backdrop-plum .blob-b { top: 10%; right: -15%; width: 50vw; height: 50vw; opacity: 0.60; background: radial-gradient(circle, #ff00bf 0%, transparent 65%); filter: blur(75px); animation: blobB 26s ease-in-out infinite; }
.backdrop-plum .blob-c { bottom: -25%; left: 25%; width: 45vw; height: 45vw; opacity: 0.40; background: radial-gradient(circle, #98036c 0%, transparent 65%); filter: blur(70px); animation: blobC 24s ease-in-out infinite; }

/* Soft plum tint band, the LTP sibling of band-pink */
.band-plum-tint { background: linear-gradient(to bottom, #fdf1f8, rgba(255,240,253,0.35), var(--color-paper)); }

/* ---- The canon LTP pricing cards (homepage + register wizard) ------------- */
.plan-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; align-items: stretch; }
@media (max-width: 810px) { .plan-cards { grid-template-columns: 1fr; } }
.plan-card {
  position: relative; border: 2px solid rgba(15,26,31,0.05); border-radius: 18px; overflow: hidden;
  background: var(--color-paper); display: flex; flex-direction: column; margin: 0; padding: 0;
  box-shadow: 0 10px 30px -15px rgba(81,38,160,0.18); font-weight: 400;
}
.plan-card.is-featured { border-color: var(--color-pink-400); }
/* Anchored to the bottom of the head, so it straddles the head-to-body seam
   whatever height the head grows to. At a fixed offset from the card top it
   landed on the subtitle the moment the cards were opened up. */
.plan-card .featured-tab {
  position: absolute; bottom: -0.8rem; left: 50%;
  transform: translateX(-50%); z-index: 1; white-space: nowrap;
}
/* The generous bottom padding is on every head, badge or not, so the three
   cards stay aligned and the badge has somewhere to sit. */
.plan-card .head {
  color: #fff; text-align: center; position: relative;
  padding: 1.1rem 0.9rem 1.85rem;
}
.plan-card .head .t { display: block; font-weight: 700; font-size: 1.2rem; color: #fff; }
.plan-card .head .d { display: block; color: rgba(255,255,255,0.88); font-size: 0.76rem; margin-top: 0.1rem; }
.plan-card.monthly .head { background: var(--ltp-navy); }
.plan-card.termly .head { background: #06696e; }
.plan-card.annual .head { background: #b80080; }
.plan-card .body { padding: 0.9rem 1rem 1rem; display: flex; flex-direction: column; gap: 0.7rem; flex: 1; }
.plan-card .tier { text-align: center; padding-block: 1.15rem; }
.plan-card .tier + .tier { border-top: 1px solid rgba(15,26,31,0.05); padding-top: 1.15rem; }
.plan-card .tier .days { display: block; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--color-muted); }
.plan-card .tier .amount { display: block; font-size: 1.5rem; font-weight: 800; color: var(--ltp-navy); line-height: 1.25; }
.plan-card .tier .per { display: block; font-size: 0.78rem; color: var(--color-muted); }
.plan-card .save { margin-top: auto; text-align: center; border-radius: 999px; padding: 0.35rem 0.6rem; font-size: 0.8rem; font-weight: 700; background: var(--color-surface); color: var(--color-muted); }
.plan-card.termly .save { background: #e2faf8; color: #06696e; }
.plan-card.annual .save { background: var(--color-pink-50); color: var(--ltp-plum-mid); }

/* ---- Sticky mobile CTA -----------------------------------------------------
   Shown only between the two sentinels (hero and final CTA band), so it can
   never sit on screen at the same time as another register button. */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: rgba(255,255,255,0.95); backdrop-filter: blur(10px);
  border-top: 1px solid rgba(15,26,31,0.1); padding: 0.6rem 1rem;
  display: none; align-items: center; justify-content: space-between; gap: 0.8rem;
  transform: translateY(110%); transition: transform 220ms ease;
}
.sticky-cta.show { transform: translateY(0); }
.sticky-cta .reviews-chip {
  font-size: 0.8125rem; font-weight: 600; color: var(--color-ink-soft);
  text-decoration: none; display: inline-flex; align-items: center; gap: 0.35rem;
  min-height: 2.75rem;
}
.sticky-cta .reviews-chip .stars { color: #e8a33d; letter-spacing: 0.08em; }
@media (max-width: 810px) { .sticky-cta { display: flex; } body.has-sticky { padding-bottom: 64px; } }

/* ---- Small LTP touches ---------------------------------------------------- */
/* Uncropped hero photo: the frame keeps the image's own aspect, so the whole
   photograph shows with no crop and no letterbox gaps whatever shape it is. */
.hero-photo.natural { margin-inline: auto; }
.hero-photo.natural img { width: 100%; height: auto; max-height: none; object-fit: fill; }

/* The fee small print row under the pricing cards */
.fees-notes { display: flex; gap: 0.6rem 2rem; flex-wrap: wrap; margin-top: 1.4rem; font-size: 0.9rem; color: var(--color-muted); }

/* Timetable and term-date tables sit inside a bordered card */
.table-card { border-radius: var(--radius); background: var(--color-paper); border: 2px solid rgba(0,52,57,0.1); padding: 0.5rem 1rem; }

/* ---- Long-document typography (the payment policy page) ------------------- */
.policy-toc { columns: 2; column-gap: 2.5rem; margin: 0; padding-left: 1.25rem; }
.policy-toc li { margin-bottom: 0.35rem; break-inside: avoid; }
.policy-toc a { color: var(--color-cyan-800); text-decoration: none; }
.policy-toc a:hover { text-decoration: underline; }
@media (max-width: 599px) { .policy-toc { columns: 1; } }

.policy-body h2 {
  font-family: var(--font-display); font-size: 1.5rem; line-height: 1.2;
  text-transform: uppercase; color: var(--color-dark); letter-spacing: -0.01em;
  margin: 2.75rem 0 1rem; scroll-margin-top: 5rem;
}
.policy-body h2:first-child { margin-top: 0; }
.policy-body h3 {
  font-family: var(--font-body); font-weight: 700; font-size: 1.0625rem;
  color: var(--color-dark); margin: 1.75rem 0 0.5rem;
}
.policy-body p { margin: 0 0 0.875rem; font-size: 0.9375rem; line-height: 1.65; color: var(--color-ink-soft); }
.policy-body p strong:first-child { color: var(--color-ink); }
.policy-body .prose-list { margin: 0 0 1rem; }
.policy-body .table-scroll { margin: 1rem 0 1.5rem; }
.policy-body .data-table td, .policy-body .data-table th { vertical-align: top; }

/* Subject cards: the camps activities treatment, borrowed */
.subject-card { border-left: 4px solid var(--color-cyan); padding-left: 1rem; }
.subject-card.alt-pink { border-left-color: var(--color-pink); }
.subject-card.alt-orange { border-left-color: var(--color-orange); }


/* ---- Section rhythm ---------------------------------------------------------
   The shared sheet runs 7rem of padding above and below every band, which puts
   224px of nothing between any two sections. Halved here rather than in the
   shared file, because the other estate sites are not complaining. */
.section    { padding-block: 3rem; }
.section-md { padding-block: 2.5rem; }
@media (min-width: 768px) {
  .section    { padding-block: 4rem; }
  .section-md { padding-block: 3.25rem; }
}

/* ---- Deadline strip ---------------------------------------------------------
   The whole strip is the link. It used to carry its own Enrol now directly
   above the nav's Enrol now, which is one button too many. */
:root {
  /* The strip's height, so the fixed header sits under it and the page clears
     both. Declared here so the layout is right before any script runs; site.js
     corrects it on load and resize (the line wraps on a phone) and zeroes it
     when the strip retires itself. */
  --strip-h: 40px;
}
.deadline-strip {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  display: block; text-decoration: none;
  background: #df009b; color: #fff;
  font-size: 0.875rem; line-height: 1.4;
  transition: background-color 160ms ease;
}
/* #df009b rather than the full brand pink: white on #ff00bf measures 3.6:1,
   which fails at this size. This reaches about 4.9:1 and still reads pink. */
.deadline-strip:hover { background: #c60089; }
/* A block, not a flex row. As a flex row the dot became its own wrap item and
   sat stranded on a line of its own above the text on a phone. Inline-block
   keeps it on the first line where a live signal belongs. */
.deadline-strip-inner {
  max-width: var(--container); margin-inline: auto;
  padding: 0.55rem var(--gutter); display: block;
}
.deadline-strip strong { font-weight: 700; }
.site-header { top: var(--strip-h); }
/* Only where the strip actually renders. register.html has no strip and does
   not load site.js, so a global rule left a permanent 40px gap above the page
   that takes the money. */
body.has-strip { padding-top: var(--strip-h); }

/* The live dot: dark against the pink, with a ring that pulses out of it. */
.deadline-dot {
  position: relative; display: inline-block; vertical-align: middle;
  width: 0.5rem; height: 0.5rem; border-radius: 999px;
  margin-right: 0.5rem; margin-bottom: 0.1rem;
  background: var(--ltp-plum-deep);
}
.deadline-dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 999px;
  border: 2px solid var(--ltp-plum-deep);
  animation: dotPulse 2s ease-out infinite;
}
@keyframes dotPulse {
  0%   { transform: scale(1);   opacity: 0.9; }
  70%  { transform: scale(2.8); opacity: 0; }
  100% { transform: scale(2.8); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .deadline-dot::after { animation: none; opacity: 0.35; }
}

/* ---- Watch the briefing -----------------------------------------------------
   Tertiary on purpose. The hero already carries two calls to action and the
   tone document asks for one per piece, so this is a link that happens to be
   a button element, not a third CTA competing for the eye. */
.watch-link {
  display: inline-flex; align-items: center; gap: 0.6rem;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--color-muted-strong); text-align: left;
}
.watch-link:hover { color: var(--color-ink); }
.watch-play {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: 999px; flex: none;
  background: var(--color-cyan-50); color: var(--color-cyan-800);
  box-shadow: inset 0 0 0 1px rgba(0,105,112,0.16);
  transition: transform 160ms ease;
}
.watch-play svg { width: 0.875rem; height: 0.875rem; margin-left: 2px; }
.watch-link:hover .watch-play { transform: scale(1.08); }
.watch-link:focus-visible { outline: 2px solid var(--color-secondary); outline-offset: 4px; border-radius: 6px; }
.watch-meta { display: block; font-size: 0.8125rem; color: var(--color-muted); }

/* ---- The overlay ------------------------------------------------------------
   Over the page, never a separate page: watching should not cost a parent
   their place in what they were reading. */
.watch-overlay { position: fixed; inset: 0; z-index: 200; display: flex;
  align-items: center; justify-content: center; padding: var(--gutter); }
.watch-overlay[hidden] { display: none; }
.watch-backdrop { position: absolute; inset: 0; background: rgba(15,10,20,0.82);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.watch-panel {
  position: relative; width: min(64rem, 100%); max-height: 92vh;
  display: flex; flex-direction: column; gap: 0.9rem;
}
.watch-panel video {
  display: block; width: 100%; height: auto; background: #000;
  border-radius: var(--radius-lg); box-shadow: 0 24px 60px rgba(0,0,0,0.45);
}
.watch-actions { display: flex; justify-content: center; }
.watch-close {
  position: absolute; top: -2.6rem; right: 0;
  width: 2.25rem; height: 2.25rem; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(255,255,255,0.28); background: rgba(255,255,255,0.1);
  color: #fff; display: flex; align-items: center; justify-content: center;
}
.watch-close:hover { background: rgba(255,255,255,0.2); }
.watch-close svg { width: 1.125rem; height: 1.125rem; }
.watch-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
@media (max-width: 640px) {
  .watch-close { top: auto; bottom: -3rem; right: 50%; transform: translateX(50%); }
}

/* ---- The parent guide -------------------------------------------------------
   The real cover, rendered from page one of the PDF. A drawn substitute was
   pretending to be a document that already has a good cover. */
.guide-row {
  display: grid; gap: 2rem; align-items: center; grid-template-columns: 1fr;
  margin-top: 3rem; padding-top: 2.5rem; border-top: 1px solid rgba(15,26,31,0.08);
}
/* Capped and centred rather than spread across the full container: three lines
   of copy in a 710px column left a hole in the middle of the row. */
@media (min-width: 820px) {
  .guide-row { grid-template-columns: minmax(0, 1fr) 15rem; gap: 3.5rem;
               max-width: 52rem; margin-inline: auto; }
}
.guide-cover { display: block; justify-self: center; width: min(15rem, 70%); }
.guide-cover img {
  display: block; width: 100%; height: auto; border-radius: 0.5rem;
  box-shadow: 0 14px 34px -10px rgba(61,0,40,0.3);
  transition: transform 180ms ease, box-shadow 180ms ease;
}
.guide-cover:hover img { transform: translateY(-4px); box-shadow: 0 20px 44px -10px rgba(61,0,40,0.38); }
@media (prefers-reduced-motion: reduce) {
  .guide-cover img, .guide-cover:hover img { transform: none; transition: none; }
}

/* ---- Term dates: a list, not a wall ----------------------------------------
   Label and date on one line with 14px between rows read as a block of text,
   especially where a date wraps. A hairline between entries turns it back
   into a list you can scan. */
.term-list dt:not(:first-of-type), .term-list dd:not(:first-of-type) {
  border-top: 1px solid rgba(15,26,31,0.07);
}
@media (max-width: 560px) {
  /* Stacked: the rule belongs above the label, and the date joins it. */
  .term-list dt { padding-top: 0.7rem; padding-bottom: 0.1rem; }
  .term-list dd { padding-top: 0; padding-bottom: 0.7rem; }
  .term-list dd:not(:first-of-type) { border-top: 0; }
}

/* ---- Tables: no line hanging under the last row --------------------------- */
.data-table tbody tr:last-child td { border-bottom: 0; }

/* The cookie banner (assets/cookies.js) in LTP's own colours: plum, never the
   camps turquoise (plan 06). */
:root {
  --cookie-banner-bg: #5F003E;
  --cookie-banner-yes: #FF58EA;
  --cookie-banner-yes-text: #2A1520;
  --cookie-banner-yes-hover: #FF98F4;
}
