@charset "UTF-8";
/* ==========================================================================
   TWSS_styles_003.css — www.toptronicwebsites.com  (part 3 of 3)
   Generated/Updated on: 2026-09-16T15:18:07+10:00
   Build Number: 004
   Version Number: (set manually by Jacques)

   © Copyright 1990-2026 Toptronic® Ltd, all rights reserved; no part of this
   document may be reproduced, modified or stored in a retrieval system, or
   transmitted in any form or by any means, electronic, mechanical,
   photocopying, recording or otherwise, without the prior written permission of
   Toptronic Limited. For copyright inquiries: jacques@toptronic.com

   Continuation from TWSS_styles_002.css

   WHAT IS IT
     The last part of the stylesheet: the big page sections (hero, dashboard
     mock, the demo band), the small movements that make the site feel alive,
     the RIGHT-TO-LEFT rules that Arabic needs, and the printing rules.

   WHY THE RIGHT-TO-LEFT PART MATTERS
     Arabic is read from the right. We never write "left" or "right" in this
     stylesheet: we write "start" and "end" (margin-inline-start, text-align:
     start, inset-inline-start). The browser then mirrors the whole layout by
     itself when <html dir="rtl"> is set — which our translation engine does
     the moment an Arabic visitor arrives. The only things that need a manual
     flip are the little CSS-drawn arrows, because a drawn arrow does not know
     which way the text runs.

   HOW THE MOVEMENT WORKS
     Elements marked class "reveal" start slightly transparent and 14 pixels
     low. A small script watches for them to scroll into view and adds
     class "is-in", which fades and lifts them. If JavaScript is off, nothing
     is ever hidden — see the ".js" guard, added by one line in each page's
     head. Nobody ever sees a blank page because a script failed.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE HERO (the first screen of every page)
   -------------------------------------------------------------------------- */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  padding-block: clamp(56px, 7vw, 96px) clamp(56px, 7vw, 92px);
  background: var(--grad-ink);
}
/* MEASURED, session 0093: with the old 160px top padding plus a hero drawing
   given 44% of the width, the home page's first button sat 194px BELOW the fold
   on a 1920x824 screen - a sales page whose first screen asks for nothing. The
   padding is smaller, the text column is wider, and the drawing is shorter. */
#hero { padding-block-start: clamp(40px, 5vw, 76px); }
.hero::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--bloom-a); }
.hero::after { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--bloom-b); }
.hero__title { color: var(--text-dk); margin-top: var(--sp-4); }
/* THE SLOGAN (session 0097). Jacques' one-line category claim, placed between
   the headline and the long paragraph by the marketing brief
   (docs/TWSS_Slogan_0097.md, ruling 1). WHY no inner <span> around the quoted
   phrase: the translation engine paints a marked element with textContent, so
   any markup nested inside would be wiped on a language switch - the whole line
   is styled as ONE element on purpose. WHY one step between the h1 and the
   sub-headline and no second colour: the brief's ruling is that a claim must be
   quieter than the headline by SIZE, not by grey, and the hero already spends
   its one accent word on the h1 - so the slogan uses the brightest text colour
   and simply sits lower in the scale. */
.slogan {
  font: 700 clamp(1.0625rem, 1.5vw, 1.375rem)/1.25 var(--font-display);
  color: var(--text-dk);
  letter-spacing: -.01em;
  margin-block: var(--sp-3) 0;
  max-width: 34ch;
  text-wrap: pretty;
}
.hero__sub { font: 400 var(--fs-lead)/1.6 var(--font-text); color: var(--muted-dk); margin-top: var(--sp-4); max-width: 62ch; }
/* Two paragraphs in a hero (work and packages) must read as two voices, not as
   one block with no separator (audit finding 3.22). */
.hero__sub + .hero__sub { font-size: 1rem; margin-top: var(--sp-4); opacity: .92; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: var(--sp-6); }
.hero--page { padding-block: clamp(48px, 6vw, 80px); }
.hero__inner { position: relative; }
@media (min-width: 900px) {
  .hero__inner { display: grid; grid-template-columns: 1.18fr .82fr; gap: clamp(28px, 3.4vw, 56px); align-items: center; }
}
.hero__stats {
  display: flex; flex-wrap: wrap; gap: clamp(20px, 3vw, 44px);
  margin-top: clamp(32px, 4vw, 48px); padding-top: var(--sp-6);
  border-top: 1px solid rgba(244, 246, 250, .10);
}
.stat { min-width: 120px; }
.stat__num {
  display: block; font: 700 var(--fs-stat)/1 var(--font-display); color: var(--text-dk);
  font-variant-numeric: tabular-nums; unicode-bidi: isolate;
}
.stat__num::before {
  content: ""; display: block; width: 24px; height: 2px; margin-bottom: 14px; background: var(--signal);
}
.stat__label { display: block; margin-top: 6px; font: 500 .8125rem/1.5 var(--font-text); color: var(--muted-dk); }
/* The hero illustration: an isometric lattice drawn with SVG lines (no image
   file, no filter, no blur — it stays sharp on every screen and weighs bytes). */
.hero__art { position: relative; aspect-ratio: 5/4; min-height: 280px; max-height: 400px; }
.hero__art::before { content: ""; position: absolute; inset: -12%; background: var(--bloom-a); }
.hero__art::after { content: ""; position: absolute; inset: -12%; background: var(--bloom-b); }
.hero__art svg { position: relative; width: 100%; height: 100%; }
/* On a narrow screen the width must come from the column, never from a minimum
   height: aspect-ratio would turn a minimum HEIGHT into a width wider than the
   phone, and the drawing would be cut off at the sides. */
@media (max-width: 899px) { .hero__art { aspect-ratio: 16/9; min-height: 0; } }

/* --------------------------------------------------------------------------
   2. THE DASHBOARD MOCK (the "not a web page, a business solution" section)
   This is a drawing made of HTML, not a picture of somebody else's software.
   The twelve bars in the chart are given their heights inline in the markup.
   -------------------------------------------------------------------------- */
.shot__body { display: grid; gap: var(--sp-6); }
.shot__body .card__list {
  display: flex; align-items: flex-end; gap: 6px; height: 140px;
  list-style: none; padding: 0; margin-top: var(--sp-5);
}
.shot__body .card__list span[style] {
  display: block; flex: 0 0 calc((100% - 66px) / 12); min-width: 4px;
  background: linear-gradient(180deg, rgba(41, 151, 255, .95), rgba(0, 113, 227, .35));
  border-radius: 4px 4px 2px 2px;
}
.shot__body .stat__num::before { display: none; }
.shot__body .stat { min-width: 0; }
.shot__body .stat__num { font-size: clamp(1.5rem, 2.6vw, 2rem); color: var(--text); }
.sec--ink .shot__body .stat__num { color: var(--text-dk); }
.shot__body .stat__label { font-size: var(--fs-micro); }
.shot__body .card { padding: 20px; }
.shot__body .table th, .shot__body .table td { padding: 9px 10px; font-size: .8125rem; }
.shot__body .card__title { font-size: .9375rem; }
/* Inside the drawn dashboard the two lower panels STACK at every width. The mock
   sits in a column about 450px wide whatever the screen size (the content column
   caps at 1180px), so side by side left the chart 175px wide with 9px bars.
   Stacked, the chart gets the full ~420px and reads as a chart. */
.shot__body .grid--2 { grid-template-columns: 1fr; }

/* --------------------------------------------------------------------------
   3. SMALL SECTION HELPERS
   -------------------------------------------------------------------------- */
.grid--2 .card + .card { margin-top: 0; }
/* These bullets are the text column's list. The rules are written with the id so
   they beat the generic .card__list, and then RE-OVERRIDDEN for the drawn
   dashboard, whose chart is also a .card__list and must stay a row of bars
   (audit finding 3.2: without the override the chart became a vertical list). */
#system .card__list { margin-top: var(--sp-6); display: grid; gap: 12px; max-width: 62ch; }
#system .card__list li { font-size: var(--fs-body); color: var(--muted-dk); }
#system .card__list li::before { border-color: var(--teal); top: .55em; }
#system .shot__body .card__list {
  display: flex; align-items: flex-end; gap: 6px; height: 140px;
  max-width: none; margin-top: var(--sp-5);
}
#proof .stat__num, #proof .stat, #proof .stat__label { color: var(--text); }
#proof .stat { min-width: 150px; }
#packages .plan__price { font-size: clamp(1.75rem, 3.2vw, 2.5rem); }
/* On the home page the plans sit on a DARK band, and ".sec--ink .plan" is a more
   specific selector than ".plan--featured", so the recommended package looked
   exactly like the other two (audit finding 3.6). This puts the emphasis back. */
#packages .plan--featured {
  background: var(--ink); border-color: rgba(41, 151, 255, .42);
  box-shadow: var(--glow-d);
}
#packages .plan--featured .plan__name { color: var(--text-dk); }
#work .shot + .shot { margin-top: 0; }
.band + .site-footer { border-top: 0; }
/* A link to #services must not put the heading underneath the sticky header. */
.sec, .hero, .band { scroll-margin-top: calc(var(--header-h) + 16px); }

/* --------------------------------------------------------------------------
   4. THE SMALL MOVEMENTS
   -------------------------------------------------------------------------- */
.js .reveal {
  opacity: 0; transform: translateY(14px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.js .reveal.is-in { opacity: 1; transform: none; transition-delay: calc(var(--i, 0) * 70ms); }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
  .marquee__track { animation: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* --------------------------------------------------------------------------
   5. RIGHT-TO-LEFT (Arabic)
   The layout mirrors itself because everything above uses start/end. Below,
   only the drawn arrows are flipped, the domain strip runs the other way, and
   letter-spacing is switched off — Arabic letters JOIN each other and extra
   spacing breaks the joins, which reads as a spelling error to an Arabic
   speaker. The same switch-off helps Chinese, where tracking looks broken.
   -------------------------------------------------------------------------- */
html[lang="ar"] body {
  --font-display: "Segoe UI", Tahoma, "Geeza Pro", "Noto Naskh Arabic", system-ui, sans-serif;
  --font-text: "Segoe UI", Tahoma, "Geeza Pro", "Noto Naskh Arabic", system-ui, sans-serif;
  line-height: 1.9;
}
html[lang^="zh"] body {
  --font-display: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, sans-serif;
  --font-text: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, sans-serif;
  line-height: 1.85;
}
html[lang="ar"] *, html[lang^="zh"] * { letter-spacing: normal !important; }
[dir="rtl"] .card__cta::after, [dir="rtl"] .shot__link::after { transform: translateY(-2px) rotate(135deg); }
[dir="rtl"] .lang::after { transform: rotate(135deg); }
[dir="rtl"] .marquee__track { animation-direction: reverse; }
[dir="rtl"] .step { padding-inline-start: 72px; padding-inline-end: 0; }
[dir="rtl"] .faq__q { padding: 20px 0 20px 44px; }

/* --------------------------------------------------------------------------
   7. THE RAIL (a scroll-snap carousel, shown on home and services)
   A row of cards the visitor scrolls sideways through. No framework: it is a
   flex row inside an overflow container with scroll-snap, so it swipes on a
   phone and scrolls with the wheel on a desktop, and needs no JavaScript.
   -------------------------------------------------------------------------- */
.rail {
  display: flex; gap: clamp(16px, 2.2vw, 26px);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-padding-inline: 4px; padding-block-end: var(--sp-4);
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail::after { content: ""; flex: 0 0 1px; }
.rail > * { flex: 0 0 min(86%, 360px); min-width: 0; scroll-snap-align: start; }
@media (min-width: 900px) { .rail > * { flex: 0 0 min(31%, 360px); } }
.rail__track { -webkit-overflow-scrolling: touch; }
/* The prev/next buttons for the rail, drawn as circles with a chevron. */
.rail__nav { display: inline-flex; gap: 10px; margin-top: var(--sp-3); }
.rail__nav button {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(244, 246, 250, .18); background: transparent;
  color: var(--text-dk); cursor: pointer; position: relative;
}
.rail__nav button::before {
  content: ""; position: absolute; inset-inline-start: 17px; top: 13px;
  width: 9px; height: 9px; border-inline-start: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
}
.rail__nav button[data-dir="next"]::before { transform: rotate(135deg); inset-inline-start: 15px; }
.rail__nav button[data-dir="prev"]::before { transform: rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .rail { scroll-behavior: auto; } }

/* The one-line "indicative in your currency" figure under a plan price. It is
   filled by TWSS_currency_001.js only when a fresh rate is known; empty
   otherwise (the page simply stays in USD). */
.plan__local { margin-top: 6px; font-size: var(--fs-micro); color: var(--muted); min-height: 1.4em; }
.sec--ink .plan__local { color: var(--muted-dk); }

/* --------------------------------------------------------------------------
   8. THE BACK-OFFICE DEMO CAROUSEL (radio-tab panels, zero JavaScript)
   Three panels shown one at a time; the visitor switches with real radio
   inputs + labels, so the arrows and Space keys work for free. The :checked
   sibling rule is the whole mechanism — no script, no state to keep in sync.
   -------------------------------------------------------------------------- */
.demo-panels { position: relative; }
/* The radios are real inputs, kept off-screen but focusable, so the arrows and
   Space keys work with no JavaScript at all. */
.demo-panels > input { position: absolute; opacity: 0; pointer-events: none; }
/* Each radio sits directly before its tab label, so "input:checked + label"
   highlights the active tab with no script. */
.demo-panels > input + label {
  display: inline-block; cursor: pointer; padding: 8px 16px; border-radius: 999px;
  border: 1px solid rgba(244, 246, 250, .2); font-size: var(--fs-micro);
  color: var(--muted-dk); transition: background var(--t), color var(--t);
}
.demo-panels > input:checked + label { background: var(--signal); color: var(--ink); border-color: transparent; }
/* A little breathing room between the tab row and the panel. */
.demo-panels > label + .demo-panel { margin-block-start: var(--sp-4); }
/* Panels sit AFTER their radio (same parent). Default: hidden. When a radio is
   checked, its matching panel (same nth-of-type position among the sibling
   divs) is shown. The first radio carries checked in the markup, so the first
   panel is visible even before any script runs. */
.demo-panels > .demo-panel { display: none; }
.demo-panels > input:nth-of-type(1):checked ~ .demo-panel:nth-of-type(1),
.demo-panels > input:nth-of-type(2):checked ~ .demo-panel:nth-of-type(2),
.demo-panels > input:nth-of-type(3):checked ~ .demo-panel:nth-of-type(3) { display: block; }
.demo-panel h3 { font: 700 1.05rem/1.3 var(--font-display); margin-block-end: 8px; color: var(--text-dk); }
.demo-panel p { font-size: var(--fs-body); color: var(--muted-dk); max-width: 54ch; }

/* --------------------------------------------------------------------------
   9. PRINTING
   One clean page of content per sheet: the navigation, the moving strip and
   the call-to-action band are removed, and every link prints the address it
   points to, because a printed page cannot be clicked.
   -------------------------------------------------------------------------- */
@media print {
  .site-header, .site-footer, .band, .marquee, .hero__art, .nav-toggle, .lang { display: none !important; }
  .sec, .hero, .sec--ink, .sec--tint { background: #fff !important; color: #000 !important; padding-block: 16px; }
  .sec--ink .h2, .sec--ink .p, .sec--ink .lead, .hero__title, .hero__sub { color: #000 !important; }
  .hero { padding-block: 24px; }
  .card, .plan, .shot__frame { box-shadow: none; border-color: #999; break-inside: avoid; }
  .plan--featured { transform: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .75em; color: #444; }
  .faq__a { display: block; }
}

/* End of TWSS_styles_003.css — the stylesheet is complete. */
