/* ---------------------------------------------------------------
   Arulero temporary single-page site — the whole of both editions.
   Zero external requests: no web fonts, no CDN, no analytics,
   no cookies. This file is served from arulero.com itself and is
   referenced relatively by each edition, so the page loads
   identically inside and outside mainland China and still renders
   when the HTML is opened straight from disk.
   Palette from idea/logo/arulero-brand-kit/README.md.

   The two editions differ only by the values reassigned in the
   html[lang="zh-Hans"] block below. There is nowhere else they can
   differ: both load this file and carry no style of their own.
   --------------------------------------------------------------- */
:root{
  color-scheme:light dark;
  --graphite:#2F3437;
  --orange:#FF6600;
  --ink:#2F3437;
  --ink-soft:#454D50;
  --muted:#5C6467;
  --line:#E2E5E6;
  --wash:#F5F6F6;
  --bg:#FFFFFF;
  --foot:#23282A;
  --notice:#FFF3EA;
  --notice-line:#FFD5BA;
  --plate:#FAFBFB;

  /* The step-3 specimen's three statuses. --notice above doubles as the
     "redo" surface, because that status is the same semantic as the notice
     the section closes with, and --ink doubles as the "missing" colour.
     EVERY TINT HERE MUST CLEAR THE FLOOR FOR --ink AS WELL AS FOR ITS OWN
     STATUS COLOUR: a tint is a surface a later editor will put body text on,
     and --ok-soft at #22342B measured 10.89:1 against --ink in the dark
     scheme versus 11.26:1 in the light one -- a loss web/page-rendering
     refuses, invisible to a matrix that only measures the status label. */
  --ok:#216E4E;
  --ok-soft:#E9F5EF;
  --redo:#C94C00;
  --flat:#EEF0F2;
  --maxw:880px;

  /* Typography — every token below is reassigned for the Simplified
     Chinese edition. Nothing else about the two editions differs. */
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --lh:1.62;
  --lh-head:1.25;
  --track:-.01em;
  --h1:2.05rem;
  --h2:1.4rem;
  --h1-sm:1.62rem;
  --h2-sm:1.25rem;
  --hero-h1-w:19ch;
  --hero-p-size:1.12rem;
  --hero-p-w:62ch;
  --tag-lh:var(--lh);
}

/* The Simplified Chinese edition -------------------------------
   Selected on lang="zh-Hans", which web/public-site § Two language
   editions at direct landing URLs already requires (never bare zh,
   which can draw Traditional glyph fallbacks).

   Latin type and CJK type do not want the same measure, leading or
   tracking, which is why these twelve values differ. A difference
   that is not a value belongs here as a value, not as a second copy
   of a rule.

   Specificity note: this block is (0,1,1) and the two data-scheme
   blocks at the foot of this file are (0,2,0), so they win. They
   assign the palette and this assigns typography, so nothing
   actually competes — recorded so that a future overlap is a known
   question rather than a surprise. */
html[lang="zh-Hans"]{
  --font:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB",
         "Microsoft YaHei","Noto Sans CJK SC","Source Han Sans SC",
         "WenQuanYi Micro Hei","Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --lh:1.85;
  --lh-head:1.42;
  --track:normal;
  --h1:1.95rem;
  --h2:1.38rem;
  --h1-sm:1.55rem;
  --h2-sm:1.22rem;
  --hero-h1-w:22ch;
  --hero-p-size:1.08rem;
  --hero-p-w:42em;
  --tag-lh:1.6;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font);
  font-size:17px;
  line-height:var(--lh);
}
.wrap{max-width:var(--maxw);margin:0 auto;padding-left:20px;padding-right:20px}
a{color:var(--ink)}
h1,h2,h3{line-height:var(--lh-head);letter-spacing:var(--track);margin:0}
h1{font-size:var(--h1);font-weight:700}
h2{font-size:var(--h2);font-weight:700;margin-bottom:.6rem}
h3{font-size:1.02rem;font-weight:700;margin-bottom:.35rem}
p{margin:0 0 1rem}
p:last-child{margin-bottom:0}
strong{font-weight:650}
.lede{font-size:1.12rem;color:var(--muted)}
.rule{width:52px;height:4px;background:var(--orange);border:0;margin:0 0 1.4rem}

/* Paragraphs set off from the block above them. The three spacings are
   the values the markup carried inline before this file existed; they
   are not a scale, and nothing should be added to them as though they
   were one. They exist as classes so that style-src can name 'self'
   alone, with no 'unsafe-inline'. */
.set-off{margin-top:1.6rem}
.set-off-sm{margin-top:1.4rem}
.note{margin-top:1rem;font-size:.95rem}

/* header ------------------------------------------------------ */
header{border-bottom:1px solid var(--line)}
.bar{display:flex;align-items:center;justify-content:space-between;gap:16px;padding-block:18px}
.logo{display:block;width:210px;height:auto;flex:0 0 auto;color:var(--ink)}
.lang{font-size:.92rem;white-space:nowrap}
.lang a{color:var(--muted);text-decoration:none;padding:4px 2px}
.lang a:hover{color:var(--orange)}
.lang .on{color:var(--ink);font-weight:650}
.lang span{color:var(--line);padding:0 6px}
.tools{display:flex;align-items:center;gap:10px}
.scheme{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;margin:0;border:0;background:none;color:var(--muted);cursor:pointer;border-radius:6px}
.scheme[hidden]{display:none}
.scheme:hover{color:var(--orange)}
.scheme:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.scheme svg{width:20px;height:20px;display:none;fill:currentColor}
.scheme[data-state="auto"] .i-auto,
.scheme[data-state="light"] .i-light,
.scheme[data-state="dark"] .i-dark{display:block}

/* hero -------------------------------------------------------- */
.hero{background:var(--graphite);color:#fff;padding-block:58px 54px}
.hero h1{color:#fff;max-width:var(--hero-h1-w)}
.hero .accent{color:var(--orange)}
.hero p{color:#CFD4D6;font-size:var(--hero-p-size);max-width:var(--hero-p-w);margin-top:1.1rem}
.jump{
  margin-top:2rem;padding-top:1.5rem;
  border-top:1px solid rgba(255,255,255,.15);
  display:flex;flex-wrap:wrap;gap:10px;font-size:.92rem;
}
.jump a{
  display:inline-block;max-width:100%;
  padding:8px 15px;
  color:#fff;text-decoration:none;font-weight:600;
  border:1px solid rgba(255,255,255,.34);border-radius:2px;
}
.jump a::after{content:"\00a0\2193";color:var(--orange);font-weight:400}
.jump a:hover,.jump a:focus-visible{background:var(--orange);border-color:var(--orange);color:#fff}
.jump a:hover::after,.jump a:focus-visible::after{color:#fff}
.jump a:focus-visible{outline:2px solid #fff;outline-offset:2px}

/* sections ---------------------------------------------------- */
section{padding-block:52px}
section + section{border-top:1px solid var(--line)}
.wash{background:var(--wash);border-top:1px solid var(--line)}

.cards{display:grid;grid-template-columns:1fr 1fr;gap:22px;margin-top:1.6rem}
.card{background:var(--bg);border:1px solid var(--line);border-top:3px solid var(--orange);padding:22px 22px 24px}
.card h3{margin-bottom:.15rem}
.card .tag{font-size:.82rem;color:var(--muted);display:block;margin-bottom:.9rem;line-height:var(--tag-lh)}
.card ul{margin:0;padding-left:1.1rem}
.card li{margin-bottom:.3rem}

/* PPE example lists, illustrated ------------------------------
   The marker is dropped because the illustration takes its place; the text
   still carries the whole item, which is what lets one file set serve three
   languages and what keeps a failed image costless.

   Specificity note: .card ul is (0,1,1), so ul.ppe-examples at (0,2,1) is what
   actually reaches padding-left. A bare .ppe-examples would lose and the list
   would keep its indent with no marker in it.

   THE PLATE IS LOAD-BEARING, NOT DECORATION. These illustrations are raster and
   cannot answer the colour scheme. Their artwork is mostly #26292b, which measures
   14.64:1 on the light page and 1.25:1 on the dark one -- so dropped straight onto
   the card the silhouettes dissolve in dark mode, while enough internal highlight
   survives that the page still looks intentional. Deleting --plate does not look
   like a bug; it looks like a tidy-up. It is not.

   The plate is DELIBERATELY DARKER IN THE DARK SCHEME, which is a measured
   exception rather than an oversight. Near-white tiles on #121516 glare. The floor
   is set by the two tones that CARRY the artwork -- charcoal mass plus brand
   orange -- so darkening trades one against the other and a MID grey is the worst
   available choice, not a safe middle:

       plate      artwork   orange
       #FAFBFB     14.12     2.83   light scheme
       #DDE1E2     11.11     2.23   dark scheme, chosen
       #9AA3A6      5.69     1.14   orange effectively gone
       #2F3437      1.16     4.29   artwork gone

   Do not darken --plate past roughly #C9CFCF, and never into the mid greys.
   web/page-rendering states the floor this obeys.

   The table is TWO tones because two carry the artwork, not because only two are
   present. eye-and-face-protection.png is about a fifth near-white -- the visor,
   which is transparent because the object is. Near-white measures 1.02 on the light
   plate and 1.32 on the dark one, so it is invisible on both and no plate changes
   that. It is affordable only because the visor is ENCLOSED by the charcoal mass:
   it reads as an aperture in a drawn frame rather than a bite out of the object.
   An illustration whose near-white runs to the artwork's edge has a hole in its
   silhouette on every plate, and web/page-rendering refuses it.

   --plate MUST be reassigned in BOTH dark selectors -- the prefers-color-scheme
   block and :root[data-scheme="dark"] -- exactly like every palette token. Setting
   only the media query leaves a reader who chose dark on a light device with the
   light plate, which nothing here detects. */
.card ul.ppe-examples{list-style:none;padding-left:0}
.card .ppe-examples li{display:flex;align-items:center;gap:12px;margin-bottom:.55rem}
.card .ppe-examples img{
  flex:0 0 40px;width:40px;height:40px;object-fit:contain;
  background:var(--plate);border-radius:8px;padding:3px;box-sizing:border-box;
}

.svc{margin-top:1.8rem}
.svc h3{font-size:1.12rem;margin-bottom:.5rem}
.svc + .svc{margin-top:2.2rem;padding-top:2.2rem;border-top:1px solid var(--line)}
.svc ul{margin:0;padding-left:1.15rem}
.svc li{margin-bottom:.35rem}

/* How it works -- the four-step diagram ------------------------
   Every colour here is a token declared at the root. This block
   declares no scheme handling of its own, which web/page-rendering
   § Colour-scheme handling is declared once requires: an unguarded
   prefers-color-scheme rule here would contradict the page in the two
   states where the reader has overridden their device, and a .dark
   selector would never match at all.

   Three layouts, and none of them wider than the page. Four columns
   from 880px -- the width at which .wrap reaches --maxw, so the content
   box stops growing and a wider window adds nothing to a card -- two
   columns from 641px, one below that. The gap and padding are tighter
   here than elsewhere on the page because at four columns they are what
   the card text is competing with: at 22px each they take 88px out of a
   194px card, at 14px and 16px they take 46px out of a 200px one.

   Nothing here sets font-family. A declaration at class specificity
   would outrank body and silently draw the Chinese edition in the
   Latin stack, which still looks plausible. */
.arulero-process__steps{
  list-style:none;display:grid;grid-template-columns:1fr 1fr;
  gap:14px;margin:1.6rem 0 0;padding:0;
}
.arulero-step{
  position:relative;min-width:0;background:var(--bg);
  border:1px solid var(--line);border-top:3px solid var(--orange);
  padding:16px 16px 18px;
}
/* The connector, drawn from two borders rather than set as the arrow
   character U+2192. That glyph takes its metrics from the font in
   effect, and the CJK stacks render it full-width, so it would sit
   wrong in one edition only. After the odd cards alone: at two columns
   the flow within a row runs left to right, and a connector after card
   2 would point out of the row at nothing. The numbers carry the
   order, so no reader depends on this. */
.arulero-step::after{
  content:"";position:absolute;z-index:2;top:25px;right:-11px;display:none;
  width:9px;height:9px;border-top:2px solid var(--orange);
  border-right:2px solid var(--orange);transform:rotate(45deg);
}
.arulero-step:nth-child(odd)::after{display:block}
.arulero-step__top{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:12px;margin-bottom:14px;
}
.arulero-step__number{
  display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;flex:0 0 32px;border-radius:50%;
  background:var(--orange);color:#fff;font-weight:700;font-size:.96rem;
}
.arulero-step__icon{width:56px;height:56px;flex:0 0 56px}
.arulero-step__icon svg{display:block;width:100%;height:100%}
.arulero-step h3{margin-bottom:.55rem;padding-bottom:.6rem;border-bottom:1px solid var(--line)}
.arulero-step p{color:var(--muted);font-size:.96rem}

/* The icons inherit --ink through currentColor, so only the parts that
   must not follow it are named. No SVG carries a style attribute:
   style-src names 'self' alone and would refuse it silently. */
.arulero-svg-accent{stroke:var(--orange)}
.arulero-svg-fill-accent{fill:var(--orange)}
.arulero-svg-circle,.arulero-svg-pen{fill:var(--bg);stroke:currentColor}

/* Green goes on a mark that depicts something SATISFIED, and nowhere else:
   step 2's three ticks and step 4's signature. --ok is the token the
   specimen's "Present" pill below already uses, and referring to the token
   rather than to its light-branch hex is what carries the scheme flip: that
   literal collapses to 2.97:1 on the dark card, against 6.17:1 on the light
   one.

   The four accents that stay orange each depict an action, an instrument or
   an artefact rather than something satisfied: step 1's arrow, step 2's
   magnifier handle, step 3's squares (the gap report) and step 4's pen tip.
   Symmetry is not a reason to green one of them.

   The ticks were refused at first -- a green tick already means "Present" in
   the legend further down this #how section, above a sample with one Present
   finding and four problems -- and then greened by the owner's decision, which
   accepts that shared mark. The three ticks are one path and move together.
   recolour-mandate-signature-green, design.md D3. */
.arulero-svg-ok{stroke:var(--ok)}

.arulero-process__notice{
  display:flex;align-items:flex-start;gap:16px;
  margin:1.8rem 0 0;padding:18px 22px;
  background:var(--notice);border:1px solid var(--notice-line);
}
.arulero-process__notice-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;flex:0 0 34px;border-radius:50%;
  background:var(--orange);color:#fff;font-weight:700;font-size:1.15rem;
}

/* The step-3 specimen -- a sample of the written gap report ------
   Sits inside #how, after the four step cards, because it is what step 3
   produces. It adds no id: the section is still named by process-title.

   Every colour is a root token. --status and --status-bg are LOCAL ALIASES
   assigned by the three .st-- classes below; they hold no value of their own
   and are deliberately absent from :root and from both dark selectors. What
   answers the reader's scheme is the token each alias points at, so this
   block declares no scheme handling -- which web/page-rendering
   -- Colour-scheme handling is declared once -- requires.

   THE MARK'S TWO COLOURS ARE MUTUALLY INVERSE, AND THAT IS LOAD-BEARING.
   The circle takes --status and the glyph inside it takes --status-bg, so the
   mark inverts with the scheme. A fixed fill does not: graphite on the dark
   "missing" pill measures 1.14:1 and green 2.14:1, so the circles vanish while
   their labels still read correctly and the table looks right. A white glyph
   fails the same way -- white on the dark --ok is 1.65:1.

   Nothing here sets font-family, for the reason recorded above the diagram: a
   declaration at class specificity outranks body and would silently draw the
   Chinese edition in the Latin stack. */
/* These two are SIBLINGS of .specimen, not parts of it -- the heading and its
   intro sit above the panel, outside the border. The double-underscore names
   below (.specimen__meta) are the ones actually inside it. */
.specimen-title{margin-top:2.4rem}
.specimen-lede{color:var(--muted);font-size:.96rem;margin:.35rem 0 1rem}
.specimen{background:var(--bg);border:1px solid var(--line);padding:18px}

/* The meta strip. Its one-pixel dividers are grid gaps over the border
   colour, which is how the page draws every other separation. */
.specimen__meta{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1px;margin:0 0 16px;background:var(--line);border:1px solid var(--line);
}
.specimen__meta>div{min-width:0;background:var(--flat);padding:10px 12px}
.specimen__meta dt{font-weight:650;font-size:.88rem}
.specimen__meta dd{margin:.1rem 0 0;color:var(--muted);font-size:.9rem}

/* A real table, so scope="col" carries the header association at every
   width and no ARIA role has to be kept in step with the layout. */
.findings{width:100%;border-collapse:collapse;font-size:.92rem}
.findings caption{text-align:left;font-weight:650;font-size:.96rem;padding-bottom:.55rem}
.findings th,.findings td{
  text-align:left;vertical-align:top;
  padding:10px 12px;border:1px solid var(--line);
}
.findings thead th{background:var(--flat);font-weight:650;font-size:.88rem}

/* The status pill. No fixed width: the Vietnamese labels are the longest of
   the three sets, and a fixed box clips one status in one edition only. */
.st--ok{--status:var(--ok);--status-bg:var(--ok-soft)}
.st--missing{--status:var(--ink);--status-bg:var(--flat)}
.st--redo{--status:var(--redo);--status-bg:var(--notice)}
.pill{
  display:inline-flex;align-items:center;gap:8px;padding:4px 10px 4px 4px;
  background:var(--status-bg);color:var(--status);
  font-weight:650;font-size:.88rem;
}
.pill__mark{
  display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;flex:0 0 22px;border-radius:50%;
  background:var(--status);color:var(--status-bg);
}
.pill__mark svg{
  display:block;width:13px;height:13px;fill:none;stroke:currentColor;
  stroke-width:4;stroke-linecap:round;stroke-linejoin:round;
}

/* The legend. Its gloss is --ink on each tint, which is why every tint has to
   clear the floor for --ink and not only for its own status colour. */
.legend{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:16px 0 0}
.legend>div{min-width:0;background:var(--status-bg);border:1px solid var(--line);padding:10px 12px}
.legend dt{display:flex;align-items:center;gap:8px;color:var(--status);font-weight:650;font-size:.9rem}
.legend dd{margin:.3rem 0 0;font-size:.86rem}

/* Four across, where the window is wide enough for four columns to be worth
   reading. Only the card row breaks out: -130px each side takes it from the
   page's 840px content box to 1100px, so the heading, the lede and the notice
   stay on the same left edge as every other section on the page and only the
   graphic is wide. The margin is a fixed length rather than a vw expression
   because vw counts the scrollbar and this must not.

   880px is where .wrap reaches --maxw: below it the content box is the
   viewport less its gutters and the columns keep narrowing, at and above it
   the box is frozen at 840px, so this is the first width at which four
   across is as good as it gets. Nothing here breaks out of that box -- the
   cards share their edges with the notice and with every heading. */
@media (min-width:880px){
  .arulero-process__steps{grid-template-columns:repeat(4,1fr)}
  .arulero-step:not(:last-child)::after{display:block}
}

dl.straight{margin:1.6rem 0 0}
dl.straight dt{font-weight:700;margin-top:1.5rem}
dl.straight dt:first-child{margin-top:0}
dl.straight dd{margin:.25rem 0 0;color:var(--ink-soft)}

/* price ------------------------------------------------------- */
.fees{margin:1.4rem 0 1.6rem;border-top:1px solid var(--line)}
.fees>div{display:grid;grid-template-columns:1fr auto;gap:6px 20px;padding:11px 0;border-bottom:1px solid var(--line)}
.fees dt{font-weight:650}
.fees dd{margin:0;color:var(--ink-soft);text-align:right}

/* contact ----------------------------------------------------- */
.contact{background:var(--graphite);color:#fff}
.contact h2{color:#fff}
.contact p{color:#CFD4D6}
.mail{
  display:inline-block;margin-top:.6rem;font-size:1.32rem;font-weight:700;
  color:var(--orange);text-decoration:none;word-break:break-all;
}
.mail:hover{text-decoration:underline}

/* footer ------------------------------------------------------ */
footer{background:var(--foot);color:#9AA3A6;font-size:.88rem;padding-block:30px}
footer a{color:#9AA3A6}
footer .legal{color:#C4CACC}
footer p{margin-bottom:.5rem}

@media (max-width:640px){
  body{font-size:16px}
  h1{font-size:var(--h1-sm)}
  h2{font-size:var(--h2-sm)}
  .logo{width:200px}
  .hero{padding-block:44px 42px}
  section{padding-block:40px}
  .cards{grid-template-columns:1fr;gap:18px}
  .arulero-process__steps{grid-template-columns:1fr;gap:20px}
  .arulero-step{padding:20px}
  .arulero-step:nth-child(odd)::after{display:none}
  /* Stacked, the connector becomes a vertical rule in the gap, aligned
     on the centre of the number above it. */
  .arulero-step:not(:last-child)::before{
    content:"";position:absolute;left:38px;bottom:-20px;
    width:2px;height:20px;background:var(--orange);
  }
  .arulero-step__icon{width:66px;height:66px;flex:0 0 66px}
  /* The specimen stacks into one card per finding. Every field stays present
     -- the supplied CSS hid the fourth between 721px and 980px, a band nothing
     in this project renders. thead is hidden from sight but not from the
     accessibility tree, so scope="col" still associates each cell with its
     column; hiding it outright would take that association with it. The
     count of hidden rules in this file is itself a check -- do not write
     that property name into a comment.
     The visible label is content:attr(data-label), NOT a literal string: one
     stylesheet serves three languages, so a label written here would render in
     English on /zh/ and /vi/. It sits above its value rather than in a
     reserved gutter, because the three editions' labels are not one width. */
  .specimen{padding:14px}
  .specimen__meta{grid-template-columns:1fr}
  .findings,.findings caption,.findings tbody,.findings tr,.findings td{display:block}
  .findings thead{
    position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;border:0;clip-path:inset(50%);
  }
  .findings tr{border:1px solid var(--line);margin-bottom:12px}
  .findings tr:last-child{margin-bottom:0}
  .findings td{border:0;border-top:1px solid var(--line);padding:9px 12px}
  .findings td:first-child{border-top:0}
  .findings td::before{
    content:attr(data-label);display:block;
    color:var(--muted);font-weight:650;font-size:.74rem;margin-bottom:.15rem;
  }
  .findings td:first-child::before{content:none}
  .legend{grid-template-columns:1fr}
  .fees>div{grid-template-columns:1fr}
  .fees dd{text-align:left}
  .bar{gap:8px 12px;flex-wrap:wrap}
  .tools{margin-left:auto;gap:4px}
}
@media (prefers-color-scheme:dark){
  :root:not([data-scheme="light"]){
    --ink:#E7EAEB;
    --ink-soft:#B9C0C2;
    --muted:#9AA3A6;
    --line:#343A3D;
    --wash:#1B1F21;
    --bg:#121516;
    --foot:#1C2123;
    --notice:#33261F;
    --notice-line:#754126;
    --plate:#DDE1E2;
    --ok:#8FDCB6;
    --ok-soft:#1D2E26;
    --redo:#FF6600;
    --flat:#252B2D;
  }
}
:root[data-scheme="dark"]{
  color-scheme:dark;
  --ink:#E7EAEB;
  --ink-soft:#B9C0C2;
  --muted:#9AA3A6;
  --line:#343A3D;
  --wash:#1B1F21;
  --bg:#121516;
  --foot:#1C2123;
  --notice:#33261F;
  --notice-line:#754126;
  --plate:#DDE1E2;
  --ok:#8FDCB6;
  --ok-soft:#1D2E26;
  --redo:#FF6600;
  --flat:#252B2D;
}
:root[data-scheme="light"]{color-scheme:light}
