/* ==========================================================================
   Site overrides — loaded after style.css (never edit the minified theme)
   ========================================================================== */

/* ==========================================================================
   Footer refinement — calmer hierarchy, tighter rhythm
   Scoped to <footer data-bs-theme="dark">. Specificity notes inline: the
   theme rules being beaten are `.nav.flex-column:not(.nav-pills) .nav-link`
   (0,4,0) and `[data-bs-theme=dark] .nav` (0,2,0).
   ========================================================================== */

/* --- Group headings: small tracked-caps labels ------------------------- */
footer .footer-heading {
	font-family: "Nunito Sans", sans-serif;
	font-size: .8125rem;              /* 13px */
	font-weight: 700;
	line-height: 1.2;
	text-transform: uppercase;
	letter-spacing: .08em;
	color: rgba(255, 255, 255, .55);  /* 5.8:1 on #202124 */
	margin: 0 0 .875rem;
}
footer .footer-heading:not(:first-child) {
	margin-top: 2.25rem;              /* gap between stacked groups */
}

/* --- Links: size/weight/colour via the theme's own tokens -------------- */
/* footer[data-bs-theme=dark] outranks the theme's dark-mode .nav token */
footer[data-bs-theme=dark] .nav {
	--bs-nav-link-font-size: .875rem; /* 14px */
	--bs-nav-link-font-weight: 400;
	--bs-nav-link-color: rgba(255, 255, 255, .65);  /* 7.7:1 */
	--bs-nav-link-hover-color: #ff9933;             /* 7.6:1 */
	line-height: 1.45;                /* inherited by .nav-link */
}

/* Padding is hard-coded by the theme at (0,4,0); mirror-and-raise to win */
footer .nav.flex-column:not(.nav-pills) .nav-link {
	padding: .3125rem 0;              /* ~30px row pitch */
}
footer .nav .nav-link:focus-visible {
	color: #ff9933;
	outline: 2px solid #ff9933;
	outline-offset: 2px;
	border-radius: 2px;
}

/* "Free" badge — scale down with the new link size */
footer a.nav-link .badge {
	font-size: .65em;
	padding: .3em .55em;
	vertical-align: middle;
}

/* --- Brand column ------------------------------------------------------ */
footer .footer-brand p:not(.small) {
	font-size: 1rem;                  /* blurb, down from 1.2rem body size */
	line-height: 1.6;
}
footer .footer-brand .small {
	font-size: .875rem;               /* company name + address */
	line-height: 1.7;
	color: rgba(255, 255, 255, .55);  /* 5.8:1 */
}
footer .footer-brand .small strong {
	font-weight: 600;
	color: rgba(255, 255, 255, .78);  /* 10.2:1 — name leads, address recedes */
}

/* --- Legal bar --------------------------------------------------------- */
footer hr {
	border-top-color: rgba(255, 255, 255, .08);  /* quiet hairline */
	opacity: 1;
}
footer .footer-copyright {
	font-size: .8125rem;              /* 13px */
	line-height: 1.5;
	color: rgba(255, 255, 255, .55);  /* 5.8:1 on #202124 */
}

/* Registration numbers: one wrapping line of nowrap label-value pairs.
   Gap-separated (no middots) so wrapped lines never dangle a separator. */
footer .footer-regs {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;          /* centred on phones, like the bar */
	column-gap: 1.25rem;
	row-gap: .125rem;
	margin-top: .375rem;
	font-size: .75rem;                /* 12px legal furniture */
	line-height: 1.6;
	color: rgba(255, 255, 255, .5);   /* 5.0:1 */
}
footer .footer-regs strong {
	font-weight: 600;
	color: rgba(255, 255, 255, .62);  /* ~7:1 — labels findable, values quiet */
}
@media (min-width: 768px) {
	footer .footer-regs {
		justify-content: flex-start;
	}
}

/* --- Social icons: ghost circles, orange fill on hover ----------------- */
/* Theme hard-codes .btn-light bg/border/colour, so override the properties
   directly; hover/active need own rules — the resting rule (0,2,1) would
   otherwise outrank .btn:hover (0,2,0) and the (0,3,0) active selectors. */
footer .btn-icon.btn-light {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, .16);
	border-radius: 50%;
	color: rgba(255, 255, 255, .65);  /* icon 7.7:1 */
}
footer .btn-icon.btn-light:hover,
footer .btn-icon.btn-light:active {
	background: #ff9933;
	border-color: #ff9933;
	color: #202124;                   /* 7.6:1 on the orange fill */
}
footer .btn-icon.btn-light:focus-visible {
	outline: 2px solid #ff9933;
	outline-offset: 2px;
}

/* ==========================================================================
   Accessibility overrides (Phase 2.8)
   ========================================================================== */

/* --- Keyboard focus: the theme ships :focus-visible{outline:0!important},
   removing focus indication sitewide. #B4740F passes the 3:1 non-text
   contrast bar on BOTH the white and #202124 grounds. ------------------- */
:focus-visible {
	outline: 2px solid #B4740F !important;
	outline-offset: 2px;
}

/* Form fields: the theme swaps the outline for a 10%-opacity drop shadow.
   Give focused fields a visible border + ring instead. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
	border-color: #B4740F;
	box-shadow: 0 0 0 3px rgba(180, 116, 15, .25);
}

/* --- Colour contrast -------------------------------------------------- */
/* Primary buttons: white on #ff9933 is 2.13:1. Ink text keeps the brand
   orange untouched and reads at 8.65:1 (5.6:1 on the hover orange). */
.btn-primary {
	--bs-btn-color: #121418;
	--bs-btn-hover-color: #121418;
	--bs-btn-active-color: #121418;
}

/* Bootstrap secondary text: raise the token alpha so small muted text
   (review-card sources etc.) reaches 4.9:1 on white */
:root {
	--bs-secondary-color: rgba(96, 98, 97, .9);
}

/* Amber eyebrow on the secondary plan card: 2.64:1 -> 4.58:1 */
.hm-secondary-plan-eyebrow {
	color: #96660F;
}

/* Orange and grey badges: white text fails on both */
.badge.bg-primary {
	color: #121418;
}
.badge.bg-secondary {
	background-color: #5f6165 !important; /* 6.3:1 with white text (was #85878a at 3.6:1) */
}

/* Buttons: the theme's own .btn:focus-visible outranks the bare rule above */
.btn:focus-visible {
	outline: 2px solid #B4740F !important;
	outline-offset: 2px;
	box-shadow: none;
}

/* Hover-opened dropdown toggles receive programmatic focus from Bootstrap;
   the open panel already shows state, so no ring on an open toggle */
.dropdown-hover .dropdown-toggle.show:focus-visible {
	outline: 0 !important;
}

/* Long-form content tables (CFML guides, fact sheets): the theme defaults table
   cells to white-space nowrap for pricing tables; these need wrapping text so the
   table stays 100% wide instead of overflowing into horizontal scroll. */
.table-prose th,
.table-prose td { white-space: normal; }

/* Carbon-negative band illustration (content-item-green-hosting include).
   Pure-CSS ambience: breathing glow, slow orbit, leaf sway, drifting
   micro-leaves. All motion is gated behind prefers-reduced-motion. */
.eco-illust { max-width: 320px; height: auto; }
.eco-breathe,
.eco-orbit { transform-box: fill-box; transform-origin: center; }
.eco-sway  { transform-box: fill-box; transform-origin: 50% 96%; }
.eco-float { transform-box: fill-box; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .eco-breathe { animation: ecoBreathe 7s ease-in-out infinite; }
  .eco-orbit   { animation: ecoSpin 48s linear infinite; }
  .eco-sway    { animation: ecoSway 6.5s ease-in-out infinite alternate; }
  .eco-float   { animation: ecoFloat 9s ease-in-out infinite; }
  .eco-f2      { animation-delay: 3s; }
  .eco-f3      { animation-delay: 6s; }
}
@media (prefers-reduced-motion: reduce) {
  .eco-float { opacity: .55; }
}
@keyframes ecoBreathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.045); } }
@keyframes ecoSpin  { to { transform: rotate(360deg); } }
@keyframes ecoSway  { from { transform: rotate(-2.2deg); } to { transform: rotate(2.4deg); } }
@keyframes ecoFloat {
  0%   { transform: translateY(6px); opacity: 0; }
  14%  { opacity: .9; }
  60%  { opacity: .5; }
  85%  { opacity: 0; }
  100% { transform: translateY(-48px); opacity: 0; }
}

/* Partner logo scenes: the logo itself stays still (brand-safe); a related
   ambient motif moves slowly behind it. Reused by feature-highlight bands. */
.logo-scene { position: relative; display: flex; align-items: center; justify-content: center; min-height: 250px; padding: 2.5rem; border-radius: 1rem; overflow: hidden; }
.logo-scene-bg { position: absolute; inset: 0; width: 100%; height: 100%; }
.logo-scene-img { position: relative; max-width: min(65%, 280px); height: auto; }
.scene-spin-a,
.scene-spin-b { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
  .scene-spin-a { animation: ecoSpin 26s linear infinite; }
  .scene-spin-b { animation: ecoSpin 38s linear infinite reverse; }
}

/* Scene animation library for the illustrated bands: status LEDs, kanban
   card, data-flow dots. All motion sits behind prefers-reduced-motion. */
.logo-scene-img-raised { margin-bottom: 3.25rem; max-width: min(78%, 340px); }
.led { transform-box: fill-box; }
.kb-check { transform-box: fill-box; transform-origin: center; }
.kb-move { transform-box: fill-box; }
.flow { transform-box: fill-box; }
@media (prefers-reduced-motion: no-preference) {
  .led   { animation: ledPulse 2.6s ease-in-out infinite; }
  .led-2 { animation-delay: .9s; }
  .led-3 { animation-delay: 1.7s; }
  .kb-check { animation: kbCheck 7s ease-in-out infinite; }
  .kb-move  { animation: kbMove 7s ease-in-out infinite; }
  .flow   { animation: flowRun 5s linear infinite; }
  .flow-2 { animation-delay: 1.7s; }
  .flow-3 { animation-delay: 3.4s; }
}
@media (prefers-reduced-motion: reduce) {
  .flow-2 { transform: translateX(108px) translateY(15px); }
  .flow-3 { transform: translateX(216px) translateY(1px); }
}
@keyframes ledPulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@keyframes kbCheck {
  0%, 38%, 100% { transform: scale(1); opacity: .55; }
  46%, 60%      { transform: scale(1.18); opacity: 1; }
}
@keyframes kbMove {
  0%       { transform: translate(0, 0); opacity: 0; }
  6%       { opacity: 1; }
  16%      { transform: translate(0, 0) rotate(0deg); }
  30%      { transform: translate(48px, -34px) rotate(2.5deg); }
  42%      { transform: translate(96px, -22px) rotate(0deg); }
  84%      { transform: translate(96px, -22px); opacity: 1; }
  94%      { transform: translate(96px, -22px); opacity: 0; }
  100%     { transform: translate(0, 0); opacity: 0; }
}
@keyframes flowRun {
  0%   { transform: translateX(0) translateY(0); opacity: 0; }
  10%  { opacity: 1; }
  50%  { transform: translateX(108px) translateY(17px); }
  88%  { opacity: 1; }
  100% { transform: translateX(216px) translateY(0); opacity: 0; }
}

/* Icon circles (theme .icon-*): flex-centre the glyph instead of relying on
   line-height, which sat FontAwesome glyphs slightly off-centre. */
.icon-sm, .icon-md, .icon-lg, .icon-xl { display: inline-flex; align-items: center; justify-content: center; }

/* CPGuard scene: threat dots approach and are stopped at the shield, which
   answers with a soft pulse. */
.gflow { transform-box: fill-box; opacity: 0; }
.guard-pulse { transform-box: fill-box; transform-origin: center; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .gflow   { animation: guardRun 5s linear infinite; }
  .gflow-2 { animation-delay: 1.7s; }
  .gflow-3 { animation-delay: 3.4s; }
  .guard-pulse   { animation: guardPulse 5s ease-out infinite; }
  .guard-pulse-2 { animation-delay: 1.7s; }
}
@media (prefers-reduced-motion: reduce) {
  .gflow-1 { opacity: .7; }
  .gflow-2 { transform: translateX(74px) translateY(14px); opacity: .7; }
  .gflow-3 { transform: translateX(148px) translateY(8px); opacity: .7; }
}
@keyframes guardRun {
  0%   { transform: translateX(0) translateY(0); opacity: 0; }
  12%  { opacity: 1; }
  55%  { transform: translateX(120px) translateY(16px); opacity: 1; }
  78%  { transform: translateX(196px) translateY(4px); opacity: 0; }
  100% { transform: translateX(196px) translateY(4px); opacity: 0; }
}
@keyframes guardPulse {
  0%, 64% { transform: scale(.55); opacity: 0; }
  72%     { opacity: .8; }
  100%    { transform: scale(1.5); opacity: 0; }
}

/* Footer certification mark: muted until hovered. */
.hm-footer-cnb { opacity: .7; transition: opacity .3s ease; }
a:hover .hm-footer-cnb, a:focus-visible .hm-footer-cnb { opacity: 1; }

/* Green-hosting page scenes: turbine, fan, bulb glow, coolant loop, gauge. */
.turbine, .fan { transform-box: fill-box; transform-origin: center; }
.bulb-halo { opacity: .18; }
.pipe-dot { transform-box: fill-box; opacity: 0; }
.gauge-needle { transform-box: fill-box; transform-origin: 50% 100%; transform: rotate(-32deg); }
@media (prefers-reduced-motion: no-preference) {
  .turbine { animation: ecoSpin 16s linear infinite; }
  .fan     { animation: ecoSpin 7s linear infinite; }
  .bulb-halo { animation: bulbGlow 4.5s ease-in-out infinite; }
  .pipe-dot  { animation: pipeFlow 4s linear infinite; }
  .pipe-2    { animation-delay: 1.3s; }
  .pipe-3    { animation-delay: 2.6s; }
  .gauge-needle { animation: needleSway 6s ease-in-out infinite alternate; }
}
@media (prefers-reduced-motion: reduce) {
  .pipe-1 { opacity: .8; }
  .pipe-2 { transform: translateY(50px); opacity: .8; }
  .pipe-3 { transform: translateY(100px); opacity: .8; }
}
@keyframes bulbGlow { 0%, 100% { opacity: .12; } 50% { opacity: .4; } }
@keyframes pipeFlow {
  0%   { transform: translateY(0); opacity: 0; }
  12%  { opacity: .9; }
  88%  { opacity: .9; }
  100% { transform: translateY(112px); opacity: 0; }
}
@keyframes needleSway { from { transform: rotate(-38deg); } to { transform: rotate(-24deg); } }

/* Screenshot framing: one consistent presentation for product UI shots and
   demo videos - soft panel, rounded media, gentle depth. */
.shot-frame { background: #f8f8f8; border-radius: 1rem; padding: 1.1rem; }
.shot-frame img, .shot-frame video { border-radius: .5rem; box-shadow: 0 10px 28px rgba(32, 33, 36, .14); display: block; width: 100%; }
.shot-frame-dark { background: rgba(255, 255, 255, .06); }
.shot-frame-flush { background: #ffffff; padding: .8rem; }

/* DDoS hero: clean traffic arcs over the shield to the server while attack
   dots die at the shield (gflow/guardRun reused from the CPGuard scene). */
.cflow { transform-box: fill-box; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .cflow   { animation: cleanRun 5s linear infinite; }
  .cflow-2 { animation-delay: 1.7s; }
  .cflow-3 { animation-delay: 3.4s; }
}
@media (prefers-reduced-motion: reduce) {
  .cflow-1 { opacity: .7; }
  .cflow-2 { transform: translateX(140px) translateY(-24px); opacity: .7; }
  .cflow-3 { transform: translateX(266px) translateY(-6px); opacity: .7; }
}
@keyframes cleanRun {
  0%   { transform: translateX(0) translateY(0); opacity: 0; }
  10%  { opacity: 1; }
  50%  { transform: translateX(166px) translateY(-26px); }
  90%  { opacity: 1; }
  100% { transform: translateX(332px) translateY(8px); opacity: 0; }
}

/* Domain-tag scene: tags bob gently. */
.tag-bob { transform-box: fill-box; }
@media (prefers-reduced-motion: no-preference) {
  .tag-bob   { animation: tagBob 6s ease-in-out infinite alternate; }
  .tag-bob-2 { animation-delay: 1.6s; }
  .tag-bob-3 { animation-delay: 3.2s; }
}
@keyframes tagBob { from { transform: translateY(0); } to { transform: translateY(-7px); } }

/* Accessible accent for orange text on light grounds (4.5:1+). */
.text-amber { color: #96660F; }

/* Support hero clock: the minute hand sweeps. */
.clock-hand { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
  .clock-hand { animation: ecoSpin 12s linear infinite; }
}

/* CTA action rows (hero + band buttons): column on mobile, row from sm up.
   Items wrap as whole units instead of breaking link text mid-line, and
   buttons never break their label. */
.cta-actions { display: flex; flex-direction: column; gap: 1rem; align-items: flex-start; }
@media (min-width: 576px) {
  .cta-actions { flex-direction: row; flex-wrap: wrap; align-items: center; }
}
@media (min-width: 992px) {
  .cta-actions { gap: 1.5rem; }
}
.cta-actions .btn { white-space: nowrap; }
.cta-actions .icon-link { white-space: nowrap; flex-shrink: 0; }

/* Icon-links inside flex-column cards: size to content, not card width. */
.card .icon-link { align-self: flex-start; }

/* ---- Tools ---------------------------------------------------------------
   Index card lift + framed monospace output blocks for tool results. */
.tool-card { transition: transform .15s ease, box-shadow .15s ease; }
.tool-card:hover { transform: translateY(-3px); box-shadow: 0 .5rem 1.5rem rgba(32,33,36,.10); }
.tool-pre {
  background: #f8f8f8;
  border: 1px solid #ececec;
  border-radius: .6rem;
  padding: 1rem 1.15rem;
  margin: 0;
  max-height: 460px;
  overflow: auto;
  font-size: .85rem;
  line-height: 1.6;
  white-space: pre;
}
.tool-pre code { color: inherit; background: none; padding: 0; }
/* Inside a dark band the light panel would glare, so invert it there.
   Scoped to Bootstrap's data-bs-theme, which is what this site actually sets. */
[data-bs-theme="dark"] .tool-pre { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.1); }
/* Grade badge for the security-headers score */
.tool-grade {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 5rem;
  height: 5rem;
  border-radius: 1rem;
  font-weight: 700;
  font-size: 2.25rem;
  line-height: 1;
}
@media (prefers-reduced-motion: reduce) {
  .tool-card { transition: none; }
  .tool-card:hover { transform: none; }
}

/* Accessible password-strength text colours (the coloured bar carries the
   visual signal; these keep the word itself readable on white, AA-compliant). */
.strength-weak    { color: #b02a37; }
.strength-medium  { color: #96660f; }
.strength-strong  { color: #0a58ca; }
.strength-vstrong { color: #146c43; }

/* Form labels: the theme default (#85878a) fails WCAG AA on white (3.6:1).
   Darken on light grounds so labels pass AA; keep them light inside dark sections. */
.form-label { color: #5f6368; }
[data-bs-theme="dark"] .form-label { color: rgba(255, 255, 255, .75); }

/* IP tool location map (self-hosted Leaflet). Low z-index so the map's own
   panes never sit above the sticky navigation or dropdowns. */
.tool-map { height: 320px; width: 100%; border-radius: .6rem; z-index: 0; }
.tool-map.leaflet-container { background: #f8f8f8; }

/* Tick lists (hero bullets and the in-page "list-group-item d-flex" lists used
   right across the site). The icon font sets its own line-height, so inside a
   flex row the glyph renders at the top of a stretched box and reads ~8px high
   against the text. Letting the icon inherit the text line-height centres the
   glyph on the first line, and start-alignment keeps it on line one when the
   label wraps instead of floating into the gutter between lines. */
li.list-group-item.d-flex { align-items: flex-start; }
li.list-group-item.d-flex > i { line-height: inherit; }

/* Alert text contrast: the theme's warning and primary alerts fail WCAG AA on
   their own tints (2.97:1 and 3.59:1). Darkening only the text keeps the
   familiar tinted panels while making the message readable. */
.alert-warning { --bs-alert-color: #6b5200; color: #6b5200; }
.alert-primary { --bs-alert-color: #7a4a10; color: #7a4a10; }

/* Feature headings: a fixed-size icon beside a title that can wrap. Centring the
   row put the icon in the gutter between two lines (25px below the first line on a
   wrapped title), so align to the top and nudge the icon down by half the leading
   to sit centred on line one. */
.hm-feature-heading { align-items: flex-start; }
.hm-feature-heading > [class*="icon-"] { margin-top: .22rem; }
/* Calibrated for the icon-span + fs-5 title pairing; headings that use a raw
   inline <svg> with a larger title keep plain centring, as their titles do not wrap. */
