/* npi-portal marketing site - shared brand palette with NPI Tab Manager
   (see afd_backend/static/styles.css for the source of these values). */

:root {
  --bg:        #14171c;
  --surface:   #1b1f26;
  --surface-2: #232832;
  --border:    #2c333f;
  --border-2:  #3a424f;
  --text:      #e6e9ee;
  --text-dim:  #9aa3b2;
  --text-faint:#6b7484;
  --accent:    #f2a541;
  --accent-ink:#1a1408;
  --logo-blue: #4169e1;
  --flag-red:  #b22234;
  --flag-white:#ffffff;
  --flag-blue: #3c3b6e;
  --radius:    10px;
  --ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --max-width: 1120px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ui);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

.wrap { max-width: var(--max-width); margin: 0 auto; padding: 0 28px; }

/* Nav */
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
}
.nav .wrap { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.brand { display: flex; align-items: center; gap: 10px; }
.brand .dot {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--logo-blue);
  box-shadow: 0 0 0 3px rgba(65,105,225,.18);
}
.brand span { font-size: 15px; font-weight: 500; letter-spacing: .2px; }

/* Products/Support/About all read in the same bright, always-on --text
   color now (not the dim/hover-to-brighten treatment other nav-links used
   to get) - only the gold underline below is what changes with state. */
.nav-links { display: flex; align-items: center; gap: 24px; font-size: 14px; color: var(--text); }

.nav-item { position: relative; }
/* Gold underline is purely an interaction/current-page indicator - font
   color is handled above now, unconditionally, so this only ever adds the
   underline itself, never changes brightness.
     - Products/Support: nav.js sets aria-expanded="true"/"false" on the
       trigger every time its dropdown opens/closes, so this lights up only
       while that menu is actually open.
     - About: not a dropdown, so it has no expanded state to hook into -
       gets the underline via a plain class="current", hardcoded onto its
       link only in about.html (the one page where being "on" it is a
       meaningful, page-load-persistent state, unlike a transient click). */
.nav-item > a[aria-expanded="true"],
.nav-links > a.current {
  border-bottom: 2px solid var(--accent); padding-bottom: 2px;
}

.dropdown {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
  display: none;
  gap: 32px;
  grid-template-columns: 180px 180px;
  z-index: 20;
  box-shadow: none;
}
/* Single-column variant (Support's dropdown - just one "Software" group, no
   second "More coming soon" column like Products has) - without this, the
   grid's two fixed 180px tracks would still both reserve space, leaving an
   empty 180px gap of dead space on the right. */
.dropdown.single { grid-template-columns: 180px; }
/* Click-to-toggle, not hover - see nav.js. Hover-based reveal (the
   original design) was fragile even with a gap-bridging pseudo-element
   over the 14px offset above: the pointer still had to travel a fairly
   precise path without ever leaving the trigger/bridge/menu, real users
   kept losing the menu before they could click anything, and hover
   doesn't work on touch devices at all. ".open" is toggled by nav.js on
   click of the "Products" link. */
.nav-item.open .dropdown { display: grid; }
.dropdown h4 {
  font-size: 11px; letter-spacing: .4px; color: var(--text-faint);
  text-transform: uppercase; margin: 0 0 10px;
}
.dropdown .item { display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: 14px; color: var(--text); }
.dropdown .item i { color: var(--logo-blue); font-size: 16px; }
.dropdown .item.soon { color: var(--text-faint); }
.dropdown .item.soon i { color: var(--text-faint); }
/* Two-line item (Cloud Files) - "(coming soon)" sits on its own indented
   line under the label instead of wrapping mid-sentence when the 180px
   column is too narrow to fit both on one line. */
.dropdown .item-lines { display: flex; flex-direction: column; }
.dropdown .item-note { font-size: 12px; padding-left: 8px; }
.dropdown .empty { font-size: 12px; color: var(--text-faint); line-height: 1.6; }

.btn {
  padding: 8px 16px; border-radius: 8px; font-size: 14px; border: 1px solid var(--border-2);
  color: var(--text); display: inline-block;
}
.btn.accent { background: var(--accent); color: var(--accent-ink); font-weight: 500; border-color: var(--accent); }

/* Hero */
.hero { text-align: center; padding: 64px 0 56px; border-bottom: 1px solid var(--border); }
.hero .eyebrow { font-size: 12px; letter-spacing: .4px; color: var(--accent); margin-bottom: 14px; }
.hero h1 { font-size: 36px; font-weight: 500; line-height: 1.25; max-width: 560px; margin: 0 auto 16px; }
/* Product-page hero heading in the same gold used for buttons, tagline,
   and feature icons elsewhere on the site - scoped to this class (not
   .hero h1 generally) so it doesn't also recolor the homepage's own
   hero heading. */
.hero h1.accent-heading { color: var(--accent); }
.hero p { font-size: 16px; color: var(--text-dim); max-width: 460px; margin: 0 auto 28px; line-height: 1.6; }
.hero .cta { display: flex; justify-content: center; gap: 12px; }
.hero .cta .btn { padding: 11px 22px; }

/* Feature group heading - sits above a .features grid when the features are
   split into labeled groups (see static/tab-manager.html) rather than one
   flat, unlabeled grid (see the homepage's single .features section). */
.features-heading {
  text-align: center; font-size: 22px; font-weight: 500;
  padding: 48px 0 24px;
}
.features-group:first-of-type .features-heading { padding-top: 8px; }

/* Simple prose page - About, and any future page that's just a heading +
   paragraphs (Support, legal, etc.) can reuse this. Narrower column than
   .wrap's default max-width since long lines of body text are harder to
   read edge-to-edge. */
.content-page { padding: 64px 0 80px; border-bottom: 1px solid var(--border); }
.content-page .wrap { max-width: 700px; }
.content-page h1 { font-size: 32px; font-weight: 500; margin: 0 0 10px; }
.content-page .tagline { font-size: 20px; font-weight: 500; color: var(--accent); text-align: center; margin: 40px 0 44px; }
.content-page p { font-size: 16px; color: var(--text-dim); line-height: 1.75; margin: 0 0 24px; }
.content-page .signature { color: var(--text); text-align: right; font-style: italic; margin-top: 40px; }

/* Feature grid */
.features {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--border); border-bottom: 1px solid var(--border);
}
.feature { background: var(--surface); padding: 26px 22px; }
.feature i { font-size: 26px; color: var(--accent); }
.feature h3 { font-size: 14px; font-weight: 500; margin: 12px 0 6px; }
.feature p { font-size: 13px; color: var(--text-dim); line-height: 1.6; margin: 0; }
/* A 7th tile is a lone leftover in the last row of a 3-column grid - center it
   instead of leaving it stuck in the left column with two empty cells beside it. */
.feature:last-child:nth-child(3n+1) { grid-column: 2; }

/* Shared sizing for the custom animated SVG icons (Stay organized,
   Geo-Redundant Servers, USA based servers) - sized to visually match the
   bumped-up 26px icon font used by the plain Tabler-icon tiles above. */
.feature-icon { width: 44px; height: 44px; margin-bottom: 2px; }
.feature-icon .icon-svg { width: 100%; height: 100%; overflow: visible; }

/* Compatibility table (static/tab-manager.html, "Compatibility" section) -
   which OSes each browser's Tab Manager extension currently runs on. A new
   --compat-green is used instead of --accent (gold) for the checkmarks -
   "supported, go" reads more clearly as green than as the same gold used
   for buttons/links/icons everywhere else on the page. */
.compat-table {
  width: 100%; border-collapse: collapse; margin: 0 0 48px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; font-size: 14px;
}
.compat-table th, .compat-table td {
  border: 1px solid var(--border); padding: 12px 16px; text-align: center;
}
.compat-table thead th { background: var(--surface-2); font-weight: 500; color: var(--text); }
.compat-table thead tr:first-child th { border-bottom: none; }
.compat-table .compat-corner { background: var(--surface); }
.compat-table .compat-browser { text-align: left; font-weight: 500; }
.compat-table .compat-note { font-weight: 400; color: var(--text-faint); font-size: 12px; }
/* Tabler's webfont build pinned here (2.47.0) predates its circle-check
   icons, so a plain ti-check is used instead - sized up and bolded to still
   read as a clear, large checkmark rather than a thin stray tick. */
.compat-table .compat-yes { font-size: 26px; font-weight: 700; color: #3ecf6e; }
.compat-table .compat-soon { color: var(--text-faint); font-size: 13px; }
@media (max-width: 720px) {
  .compat-table { display: block; overflow-x: auto; }
}

/* ---- Stay organized: globes flying into a folder ------------------------ */
/* Matches the USA icon's 132px - the largest of the custom animated icons -
   so all six read as the same size (Built to be trusted is the one
   intentionally-left-plain Tabler icon and isn't part of this sizing). */
.icon-organize { width: 132px; height: 132px; }
.icon-organize .folder-back,
.icon-organize .folder-front { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.4; }
.icon-organize .folder-back { opacity: .85; }
.icon-organize .globe { fill: var(--accent); }
.icon-organize .globe-grid { fill: none; stroke: var(--surface); stroke-width: 0.8; }
/* The band sits on top of the grid lines (paint order in index.html) so it
   masks whatever crosses behind it, same as the reference image's solid
   band cutting across the globe's wireframe. */
.icon-organize .globe-band { fill: var(--surface); }
.icon-organize .globe-band-text {
  fill: var(--accent);
  font-family: var(--ui);
  font-weight: 800;
  font-size: 4.96px;
  text-anchor: middle;
  dominant-baseline: middle;
}
/* NOTE: each of these classes lives on an INNER <g>, one level below a plain
   (non-animated) positioning <g transform="translate(x,y)"> - see index.html.
   A CSS `transform` from an animation fully REPLACES an element's own
   `transform` attribute rather than combining with it, so if the positioning
   translate lived on this same animated element, it would simply be
   discarded the moment the animation starts (this was the actual bug behind
   the globes rendering left of/away from the folder - they were animating
   from the SVG's raw (0,0) origin, not from their intended start point). */
.icon-organize .globe { transform-origin: center; transform-box: fill-box; animation-duration: 5s; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
/* All three run the exact same timing (no stagger) so they visibly move
   TOGETHER, converging on the folder's slot in unison. Each has its own
   keyframes because each starts from a different spread-out point but all
   three converge on the same spot above the folder. */
.icon-organize .globe-1 { animation-name: globeFly1; }
.icon-organize .globe-2 { animation-name: globeFly2; }
.icon-organize .globe-3 { animation-name: globeFly3; }
/* Each globe travels from its spread-out start down to (32,23) in absolute
   terms. That lands the WWW band (which sits at the globe's own vertical
   center) just above the folder-front's top edge (y25), so the band and its
   text stay fully readable in the final peeking pose - only the lower,
   unlabeled part of the globe is actually covered/hidden behind the front
   pocket (paint order: front pocket is drawn after the globes - see
   index.html). Because all three converge on the SAME point, they fully
   overlap and read as one globe peeking out. Translate only - no spin. (Two
   earlier spin attempts, a flat rotate() and then a pole-axis meridian
   sweep, never quite landed, and a later WWW-band redesign made spinning
   moot anyway - Adrian asked to drop the spin entirely and just have the
   three globes fan out and converge.) They hold at the settled position for
   a beat, then fade out right at the very end of the loop so the reset back
   to the spread starting positions is invisible rather than a visible jump.
   No separate "peek" element - that was producing a second, disconnected
   upward pop after the three globes had already arrived, which read as a
   stray fourth globe. */
@keyframes globeFly1 {
  0%, 20%   { transform: translate(0,0);        opacity: 1; }
  68%       { transform: translate(24px,21px);  opacity: 1; }
  96%       { transform: translate(24px,21px);  opacity: 1; }
  100%      { transform: translate(24px,21px);  opacity: 0; }
}
@keyframes globeFly2 {
  0%, 20%   { transform: translate(0,0);        opacity: 1; }
  68%       { transform: translate(0,21px);      opacity: 1; }
  96%       { transform: translate(0,21px);      opacity: 1; }
  100%      { transform: translate(0,21px);      opacity: 0; }
}
@keyframes globeFly3 {
  0%, 20%   { transform: translate(0,0);        opacity: 1; }
  68%       { transform: translate(-24px,21px); opacity: 1; }
  96%       { transform: translate(-24px,21px); opacity: 1; }
  100%      { transform: translate(-24px,21px); opacity: 0; }
}

/* ---- Geo-Redundant Servers: two data centers, orbiting sync arrows ------ */
/* Matches the USA icon's 132px, same square-container-scales-the-viewBox
   approach as .icon-usa below. */
.icon-georedundant { width: 132px; height: 132px; }
.icon-georedundant .dc-rect { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.4; }
.icon-georedundant .dc-slot { stroke: var(--accent); stroke-width: 1; opacity: .55; }
.icon-georedundant .dc-led { fill: var(--accent); }
.icon-georedundant .dc-link { stroke: var(--accent); stroke-width: 1.2; stroke-dasharray: 2.5 2.5; opacity: .7; }
.icon-georedundant .orbit-arrow {
  fill: var(--accent);
  offset-rotate: auto;
  animation: orbit 3.2s linear infinite;
}
/* Two separate arcs, each clear of the dashed link line (y32) the whole way
   - the top one bows up (control y4, actual peak ~y16), the bottom one bows
   down (control y60, actual valley ~y48), both with a good margin either
   side of the line rather than skimming it. Authored in OPPOSITE directions
   (top runs left tower -> right tower, bottom runs right tower -> left
   tower) so with offset-rotate:auto they visibly point and travel opposite
   ways at the same time, rather than one arrow chasing another around a
   single shared loop. Each arc has two arrows (base + .arrow-delay-b), half
   a cycle (1.6s of the 3.2s loop) apart, so as one fades out the other is
   fading back in - reads as continuous flow along the arc instead of a
   single blip. The top and bottom pairs are additionally offset from each
   other by a quarter cycle (0.8s) purely for visual variety. */
.icon-georedundant .arrow-top { offset-path: path('M20,28 Q48,4 76,28'); }
.icon-georedundant .arrow-bottom { offset-path: path('M76,36 Q48,60 20,36'); animation-delay: -0.8s; }
.icon-georedundant .arrow-top.arrow-delay-b { animation-delay: -1.6s; }
.icon-georedundant .arrow-bottom.arrow-delay-b { animation-delay: -2.4s; }
@keyframes orbit {
  0%      { offset-distance: 0%;   opacity: 0; }
  8%      { opacity: 1; }
  92%     { opacity: 1; }
  100%    { offset-distance: 100%; opacity: 0; }
}

/* ---- USA based servers: USA silhouette, U/S/A fading red-white-blue ----- */
/* 200% of the original 66px size (which was itself ~1.5x the base 44px
   icon); the SVG's viewBox scales the shape and letters together, so only
   the container size needs to change. */
.icon-usa { width: 132px; height: 132px; }
.icon-usa .usa-shape { fill: var(--accent); }
.icon-usa .usa-letter {
  font-family: var(--ui); font-weight: 800; font-size: 13px;
  text-anchor: middle; dominant-baseline: middle;
  animation: usaFade 3.6s ease-in-out infinite;
}
/* All three letters fade in and out together, in sync (no per-letter delay) */
.icon-usa .usa-u { fill: var(--flag-red); }
.icon-usa .usa-s { fill: var(--flag-white); }
.icon-usa .usa-a { fill: var(--flag-blue); }
/* Dims down and brightens back up, but never disappears entirely */
@keyframes usaFade {
  0%, 100% { opacity: .4; }
  50%      { opacity: 1; }
}

/* ---- Live Update: wind-up alarm clock, ticking minute hand -------------- */
/* Matches the USA icon's 132px so all the custom animated icons read as the
   same size (this one used to be sized off the plain 26px Tabler icon it
   replaced, which left it noticeably smaller than the others). */
.icon-liveupdate { width: 132px; height: 132px; }
.icon-liveupdate .clock-leg { stroke: var(--accent); stroke-width: 2; stroke-linecap: round; }
.icon-liveupdate .clock-bell,
.icon-liveupdate .clock-case { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.4; }
.icon-liveupdate .clock-bell-rim { fill: none; stroke: var(--accent); stroke-width: 1; opacity: .55; }
.icon-liveupdate .clock-knob { stroke: var(--accent); stroke-width: 0.9; stroke-linecap: round; }
.icon-liveupdate .clock-hammer-head { stroke: var(--accent); stroke-width: 1.2; stroke-linecap: round; }
.icon-liveupdate .clock-hash { stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; }
.icon-liveupdate .clock-center { fill: var(--accent); }
/* The hand is drawn directly in the icon's absolute 0-64 coordinates (it
   only needs to rotate, never translate, so there's no need for the
   nested-group positioning trick used elsewhere in this file) - so a plain
   pixel-unit transform-origin pinned to the case's center (32,40) is fine. */
.icon-liveupdate .clock-hand {
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  transform-origin: 32px 40px;
  animation: clockTick 6s steps(6, end) infinite;
}
/* steps(6, end) does the "hold, then instantly jump" ticking motion for
   free - one jump per second, 6 per loop, landing on the hour/:10/:20/:30/
   :40/:50 positions Adrian described, no hand-authored hold keyframes
   needed. */
@keyframes clockTick {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ---- Lightweight by design: CPU chip with data pulses on 4 sides -------- */
/* Matches the USA icon's 132px, for the same reason as .icon-liveupdate
   above. */
.icon-cpu { width: 132px; height: 132px; }
.icon-cpu .cpu-chip { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.6; }
.icon-cpu .cpu-pin { stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; }
/* Each small "data" tick rides a straight offset-path further out than the
   static pins. offset-rotate is left at 0 (not `auto`) because the ticks
   are plain little capsules, not arrows - they don't need to point along
   the path, just slide along it. Reusing the same fade-in/hold/fade-out
   keyframe shape as the geo-redundant orbit arrows. */
.icon-cpu .cpu-tick {
  fill: var(--accent);
  offset-rotate: 0deg;
  animation: cpuFlow 2.6s ease-in-out infinite;
}
/* One tick per side plays in reverse (same path, same keyframes, time
   flipped) so offset-distance counts down instead of up - the element
   travels the path in the opposite spatial direction. That's what gives
   each side BOTH directions of travel at once (in on one tick, out on the
   other) instead of a single uniform flow. */
.icon-cpu .cpu-tick.reverse { animation-direction: reverse; }
@keyframes cpuFlow {
  0%   { offset-distance: 0%;   opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}
.icon-cpu .tick-top-1    { offset-path: path('M27,18 L27,6'); }
.icon-cpu .tick-top-2    { offset-path: path('M37,18 L37,6'); }
.icon-cpu .tick-bottom-1 { offset-path: path('M27,46 L27,58'); }
.icon-cpu .tick-bottom-2 { offset-path: path('M37,46 L37,58'); }
.icon-cpu .tick-left-1   { offset-path: path('M18,27 L6,27'); }
.icon-cpu .tick-left-2   { offset-path: path('M18,37 L6,37'); }
.icon-cpu .tick-right-1  { offset-path: path('M46,27 L58,27'); }
.icon-cpu .tick-right-2  { offset-path: path('M46,37 L58,37'); }

/* ---- Recover CPU and RAM: recycle-arrow triangle, spins with the flow --- */
/* Matches the USA icon's 132px, for the same reason as .icon-liveupdate
   above. */
.icon-recycle { width: 132px; height: 132px; }
/* One rigid group (three curved bands + three arrowheads, 120deg apart,
   generated with exact trig so the gaps/bands are evenly spaced) - spinning
   the whole group keeps it a perfect triangle at every frame (nothing
   distorts independently), and the spin direction matches the way the
   arrowheads already lead, so it reads as the arrows themselves driving the
   rotation rather than the triangle spinning underneath static arrows. */
.icon-recycle .recycle-spin {
  fill: var(--accent);
  transform-origin: 32px 32px;
  animation: recycleSpin 4s linear infinite;
}
@keyframes recycleSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ---- Built to be trusted: shield + lock, 6 shining rays ------------------ */
/* 25% smaller than the other icons' shared 132px - the shield read as too
   large at full size. */
.icon-trusted { width: 99px; height: 99px; }
.icon-trusted .trust-shield { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.6; }
.icon-trusted .trust-lock-body { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.4; }
.icon-trusted .trust-lock-shackle { fill: none; stroke: var(--accent); stroke-width: 1.6; }
/* Each ray is a small capsule that travels outward along its own straight
   offset-path (fade in, hold, fade out - the same keyframe shape as the
   geo-redundant orbit arrows and the CPU data ticks), with
   offset-rotate:auto so it tilts to match its own diagonal direction
   automatically instead of needing 6 hand-rotated copies. */
.icon-trusted .shine-ray {
  fill: var(--accent);
  offset-rotate: auto;
  animation: shieldShine 2.4s ease-in-out infinite;
}
@keyframes shieldShine {
  0%   { offset-distance: 0%;   opacity: 0; }
  15%  { opacity: 1; }
  75%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}
/* Uniform start/end radii (26/34 from the shield's visual center) clear the
   shield's silhouette at every angle - it's taller than it is wide, so the
   same radius that clears the pointed top/bottom corners leaves a bit of
   extra room at the narrower left/right sides, which still reads fine as a
   sparkle. Staggered delays (2.4s / 6 rays = 0.4s apart) make the six
   twinkle in sequence around the shield rather than firing all at once.
   Rays 5 and 6 (the top two) are the exception to the uniform 26/34 radius:
   after the shield was widened 25%, its top taper - narrow right at the
   point (32,8), flaring out to full width by y=11 - meant these two rays'
   near point landed too close to (and, at a first attempt, inside) the
   new, wider silhouette. Fixed by translating both points of each path
   straight up by 4 total (10.5->6.5, 3.6->-0.4) - same dx/dy, so the
   outward direction and travel distance are unchanged.

   Note this had to account for more than just the path's start point: each
   ray rect is centered on its offset-path anchor (it spans -2.5 to +2.5
   locally, with offset-rotate:auto aligning that local x-axis to the
   direction of travel), so HALF the ray's own length trails backward,
   toward the shield, from wherever the anchor sits. A shift that only
   cleared the anchor point itself still let that trailing half overlap the
   shield - the first attempt at this fix (a 1.5 shift, 10.5->9) did exactly
   that. This larger shift keeps the ray's full rendered shape, not just its
   anchor, above the shield's top curve. */
.icon-trusted .ray-1 { offset-path: path('M58,33 L66,33');     animation-delay: 0s; }
.icon-trusted .ray-2 { offset-path: path('M45,55.5 L49,62.4'); animation-delay: -0.4s; }
.icon-trusted .ray-3 { offset-path: path('M19,55.5 L15,62.4'); animation-delay: -0.8s; }
.icon-trusted .ray-4 { offset-path: path('M6,33 L-2,33');      animation-delay: -1.2s; }
.icon-trusted .ray-5 { offset-path: path('M19,6.5 L15,-0.4');  animation-delay: -1.6s; }
.icon-trusted .ray-6 { offset-path: path('M45,6.5 L49,-0.4');  animation-delay: -2.0s; }

/* Products list */
.products { padding: 48px 0; }
.products .label { font-size: 12px; color: var(--text-faint); margin-bottom: 16px; }
.product-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 22px 24px; display: flex; align-items: center; justify-content: space-between;
}
.product-card .left { display: flex; align-items: center; gap: 16px; }
.product-card .icon {
  width: 40px; height: 40px; border-radius: 8px; background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
}
.product-card .icon i { color: var(--logo-blue); font-size: 20px; }
.product-card .name { font-size: 15px; font-weight: 500; }
.product-card .desc { font-size: 13px; color: var(--text-dim); }

/* CTA band */
.cta-band { padding: 8px 0 56px; text-align: center; }
.cta-band h2 { font-size: 20px; font-weight: 500; margin-bottom: 20px; }

/* Footer - single left-aligned column (brand, a spacer, then Support and
   Contact Us as their own lines) rather than the old two-column
   space-between row. Same on every page (about.html, index.html,
   signup.html, tab-manager.html) since the markup is identical on all four. */
.footer {
  border-top: 1px solid var(--border); padding: 24px 0; font-size: 12px; color: var(--text-faint);
}
.footer .wrap { display: flex; flex-direction: column; align-items: flex-start; }
.footer-brand { color: var(--text-dim); }
.footer-spacer { height: 16px; }
/* Support / Contact Us - both a native <details> so the expand/collapse
   works with zero JS (and is keyboard/screen-reader accessible for free) on
   every page, no shared script needed. No disclosure arrow/marker on
   purpose (Adrian's request) - each should read as a plain line flush-left
   with "New Practical Innovations" above it, not look like an obvious
   dropdown; still just as clickable either way. Shared class (.footer-
   expand) since Support and Contact Us need identical behavior/styling -
   only their revealed content differs (Support: a single inert "Tab
   Manager" placeholder, no link yet; Contact Us: the four mailto: links). */
.footer-expand summary { cursor: pointer; padding: 4px 0; list-style: none; }
.footer-expand summary::-webkit-details-marker { display: none; }
.footer-expand summary:hover { color: var(--text-dim); }
.footer-expand-list { display: flex; flex-direction: column; gap: 4px; margin: 4px 0 2px 16px; }
.footer-expand-list a { color: var(--text-faint); }
.footer-expand-list a:hover { color: var(--text-dim); text-decoration: underline; }

@media (max-width: 720px) {
  .nav-links { gap: 14px; font-size: 13px; }
  .features { grid-template-columns: 1fr; }
  .dropdown { grid-template-columns: 1fr; left: 0; transform: none; }
}

/* ===========================================================================
   Sign-up flow (static/signup.html) - added 2026-08-05
   =========================================================================== */
.signup-wrap { max-width: 640px; margin: 0 auto; padding: 56px 28px 80px; }

.signup-steps {
  display: flex; align-items: center; justify-content: center;
  gap: 8px; margin-bottom: 40px; font-size: 12px; color: var(--text-faint);
}
.signup-steps .step { display: flex; align-items: center; gap: 8px; }
.signup-steps .num {
  width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--border-2);
  display: flex; align-items: center; justify-content: center; font-size: 11px;
  color: var(--text-dim);
}
.signup-steps .step.active .num { border-color: var(--accent); color: var(--accent); }
.signup-steps .step.done .num { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.signup-steps .sep { width: 24px; height: 1px; background: var(--border-2); }

.signup-panel h1 { font-size: 26px; font-weight: 500; margin: 0 0 8px; text-align: center; }
.signup-panel .sub { font-size: 14px; color: var(--text-dim); text-align: center; margin: 0 0 32px; }

.plan-picker { display: flex; flex-direction: column; gap: 12px; margin-bottom: 28px; }
.plan-card {
  display: block; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px 20px; cursor: pointer;
}
.plan-card:has(input:checked) { border-color: var(--accent); background: var(--surface-2); }
.plan-card .head { display: flex; align-items: center; gap: 10px; }
.plan-card .head strong { font-size: 15px; font-weight: 500; }
.plan-card .price { font-size: 12px; color: var(--text-faint); margin-left: auto; }
.plan-card .blurb { font-size: 13px; color: var(--text-dim); margin: 6px 0 0 26px; }
.plan-card .limits { font-size: 12px; color: var(--text-faint); margin: 4px 0 0 26px; }
.plan-card .trial { font-size: 12px; color: var(--accent); margin: 4px 0 0 26px; }
.plan-card.contact { cursor: default; }
.plan-card.contact .head strong { display: flex; align-items: center; gap: 10px; }

/* A plan-card that's actually a <button> (the "upgrade to Collaborate"
   prompt in place of Paid - Tier 2) rather than a radio label - reset the
   native button defaults so it still reads as one of the cards, and drop
   the 26px left-indent the other cards use to line their text up under a
   radio bubble this one doesn't have. */
button.plan-card.cta {
  width: 100%; text-align: left; font: inherit; color: inherit; border: 1px solid var(--border);
}
.plan-card.cta:hover { border-color: var(--border-2); }
.plan-card.cta .blurb { margin-left: 0; }

.signup-actions { display: flex; justify-content: center; gap: 12px; margin-top: 8px; }
.signup-actions .btn { padding: 11px 28px; cursor: pointer; font-family: var(--ui); font-size: 14px; }
.signup-actions .btn:disabled { opacity: .5; cursor: default; }
/* Back button - deliberately the inverse of .btn.accent (gold background,
   near-black text): black background, gold text/border. A plain gold
   border is needed for the button to read as a distinct control at all,
   since the page background is itself near-black. */
.signup-actions .btn.invert { background: var(--accent-ink); color: var(--accent); border-color: var(--accent); }

.signup-summary {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px 20px; margin-bottom: 24px; font-size: 13px; color: var(--text-dim);
}
.signup-summary strong { color: var(--text); }

.payment-placeholder-note {
  background: var(--surface-2); border: 1px dashed var(--border-2); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 20px; font-size: 12px; color: var(--text-faint); line-height: 1.6;
}
.payment-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 8px; }
.payment-fields .full { grid-column: 1 / -1; }
.payment-fields label { display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 6px; }
.payment-fields input {
  width: 100%; background: var(--surface); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 10px 12px; color: var(--text); font-family: var(--ui); font-size: 14px;
}
.payment-fields input:focus { outline: none; border-color: var(--accent); }

.signup-download { text-align: center; }
.signup-download .checkmark {
  width: 56px; height: 56px; border-radius: 50%; background: var(--accent);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;
  font-size: 26px; color: var(--accent-ink);
}
.download-buttons { display: flex; justify-content: center; gap: 12px; margin: 24px 0; }
.download-buttons .btn { padding: 11px 24px; }
.signup-download .later { font-size: 13px; color: var(--text-faint); margin-top: 8px; }

.signup-error {
  background: rgba(178,34,52,.12); border: 1px solid rgba(178,34,52,.4); border-radius: 8px;
  padding: 12px 14px; font-size: 13px; color: var(--text); margin-bottom: 20px; display: none;
}
.signup-error.show { display: block; }

/* ---- Step 1: account type (Personal / Collaborate / Corporate) ---------- */
.category-step { display: flex; align-items: flex-start; gap: 24px; margin-bottom: 28px; }
.category-buttons { display: flex; flex-direction: column; gap: 14px; flex: 1 1 auto; min-width: 0; }
.category-btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  text-align: left; width: 100%; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px; cursor: pointer; font-family: var(--ui);
  color: var(--text);
}
.category-btn strong { font-size: 15px; font-weight: 500; }
.category-btn .desc { font-size: 12px; color: var(--text-dim); line-height: 1.5; }
.category-btn .soon {
  font-size: 10px; letter-spacing: .4px; text-transform: uppercase; color: var(--text-faint); margin-top: 2px;
}
.category-btn.active { border-color: var(--accent); background: var(--surface-2); }
.category-btn:not(:disabled):hover { border-color: var(--border-2); }
.category-btn:disabled { cursor: default; opacity: .45; }

/* Roughly matches the combined height of the three stacked buttons to their
   left, per Adrian's spec ("the size of the three buttons in height and
   width"). */
.category-image {
  flex: 0 0 220px; width: 220px; height: 220px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center; padding: 22px;
}
.category-image svg { width: 100%; height: 100%; }
/* Original, hand-drawn icons (not traced from any reference image) - solid
   gold silhouettes matching the accent color already used for headings/links
   sitewide, in the same house style as the animated feature icons above. */
.category-icon-svg .ci-shape { fill: var(--accent); }

/* Personal: the two rear people fade in/out on a staggered cycle - center
   person is never hidden. Left leads (fades in first, fades out first),
   right follows, matching the sequence Adrian described: center alone ->
   left in -> right in -> both visible -> left out -> right out -> repeat.
   Neither ever reaches full opacity - they cap out at .75 (per Adrian's
   request that they never fully fade in) before fading back out again. */
.category-icon-svg .ci-back-left { animation: personalFadeLeft 8s ease-in-out infinite; }
.category-icon-svg .ci-back-right { animation: personalFadeRight 8s ease-in-out infinite; }
@keyframes personalFadeLeft {
  0%   { opacity: 0; }
  15%  { opacity: .75; }
  65%  { opacity: .75; }
  80%  { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes personalFadeRight {
  0%   { opacity: 0; }
  35%  { opacity: 0; }
  50%  { opacity: .75; }
  90%  { opacity: .75; }
  100% { opacity: 0; }
}

/* Collaborate: four small arrowheads, evenly spaced around the same circle
   the ring used to trace, spinning continuously in place of the old static
   ring line - reuses .icon-recycle's existing spin keyframe (see the
   feature-icon rules above) rather than defining an identical one twice. */
.category-icon-svg .ci-spin {
  fill: var(--accent);
  transform-origin: 32px 32px;
  animation: recycleSpin 4s linear infinite;
}

/* Corporate: each of the 12 servers (two stacks of six) has its own row of
   three tiny status-light squares, 36 in total. Every one blinks hard
   on/off (no fade - steps() rather than an eased transition) on a 1s cycle,
   toggling roughly every half second per Adrian's spec. Each square's
   animation-delay is a distinct fraction of that 1s cycle (see the i*0.37
   mod 1 sequence noted in signup.html), so the 36 lights read as
   independently random rather than pulsing in unison or in a visible
   pattern.

   This animates FILL COLOR (gold <-> the card's dark surface color), not
   opacity - the squares sit directly on top of the gold server body, so an
   earlier version that only toggled opacity was invisible: transparent gold
   over solid gold looks identical to opaque gold over solid gold, there's
   nothing to see either way. Toggling to a genuinely different color (the
   same dark "cutout" color used elsewhere in these icons) is what actually
   produces a visible blink regardless of what's underneath. */
.category-icon-svg .ci-blink {
  animation: ciBlink 1s steps(1, end) infinite;
}
@keyframes ciBlink {
  0%, 49%   { fill: var(--accent); }
  50%, 100% { fill: var(--surface); }
}

@media (max-width: 560px) {
  .payment-fields { grid-template-columns: 1fr; }
  .signup-steps { font-size: 11px; }
  .category-step { flex-direction: column; }
  .category-image { width: 100%; height: 200px; flex-basis: auto; }
}
