/* ============================================================================
   ovation.css — OVATION 欧韦 group site (English edition).

   ── The brand, and why the colours are split the way they are ───────────────
   The palette is the mark's own: an open charcoal ring (#353536) with a red
   folded corner (#EE2C29) and a yellow triangle (#F5D300) in the gap. The ring
   IS the O, which is why the wordmark alone reads VATION and only spells the
   name when the two are set together.

   It was blue and orange-red until the company asked for the site and the mark
   to agree. That earlier scheme was built around a story of two letters — a V
   whose strokes met at a point — and there is no V: it came from a placeholder
   that stood in until the designers' files arrived. The hues moved; the reason
   for having two of them did not.

   So colour here is not decoration, it is the site's navigation: anything about
   making things is charcoal, anything about trade is red, and the group level —
   where the two meet — uses both. The yellow is the triangle: an accent, in a
   rule or an edge, never as a text colour. Keep that rule when adding pages, or
   the scheme stops meaning anything.

   ── Layout vocabulary ───────────────────────────────────────────────────────
   Deliberately the same class names as nexiuni.css on the NexiUni site
   (.wrap / .nav / .hero / .section / .cards / .card / .cta / .footer), so a
   page written for one reads correctly in the other.

   The Chinese edition loads this file AND css/ovation-cn.css, which overrides
   the parts where a Chinese corporate site is conventionally different. Shared
   structure stays here; nothing language-specific belongs in this file.
   ============================================================================ */

:root{
  /* ── Brand ───────────────────────────────────────────────────────────────
     Taken from the identity itself: the ring is #353536, the folded corner
     #EE2C29, the triangle #F5D300. The site was blue and orange-red, chosen
     before the mark existed and while a placeholder was standing in for it;
     the company asked for the two to agree, so the hues moved to the mark.

     WHAT DID NOT CHANGE IS THE ENCODING. One colour still means making things
     and the other still means trade, because that is navigation rather than
     decoration — a reader who has seen two pages knows which half of the
     business a page belongs to before reading a word of it.

     The names say what they are now. A token called --mark holding a charcoal
     is a trap for whoever edits this next. */
  --mark:#353536;         /* the ring — making things */
  --mark-d:#25252a;
  --mark-deep:#1b1b1f;    /* dark end of the gradient, and the footer ground */
  --mark-soft:#f2f2f1;

  --red:#ee2c29;          /* the folded corner — international trade */
  --red-d:#c41f1c;
  --red-soft:#fdeeed;

  /* The triangle. An accent, used where the mark uses it: sparingly, in a rule
     or an edge, and never as a text colour — #F5D300 on white is unreadable.
     --yellow-d is the same hue taken down far enough to hold its own as a filled
     dot or a 3px edge, which is where Beijing's card wears it. */
  --yellow:#f5d300;
  --yellow-d:#d8bc00;

  --ink:#1f1f20; --muted:#6a6a6e; --line:#e5e3de; --soft:#f7f6f4; --white:#fff;

  --grad-mark:linear-gradient(118deg,var(--mark-deep) 0%,var(--mark) 62%,#4a4a4d 100%);
  --grad-red:linear-gradient(118deg,#8f1512 0%,var(--red) 58%,#f2564f 100%);
  /* The group gradient runs charcoal → red: the whole company in one band, and
     the mark's own two colours in the order the mark sets them. */
  --grad-group:linear-gradient(118deg,var(--mark-deep) 0%,var(--mark) 45%,var(--red) 100%);
  /* 深圳页专用的灰绿。不是 logo 的颜色——是客户单独为这一页要的。 */
  --grad-sage:linear-gradient(118deg,#27322c 0%,#3c4c43 52%,#5a6e61 100%);

  --radius:14px; --shadow:0 1px 2px rgba(31,31,32,.05); --shadow-l:0 10px 34px rgba(27,27,31,.12);
  --wrap:1180px;
}


*{box-sizing:border-box;}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;}
body{margin:0;color:var(--ink);background:var(--white);line-height:1.65;
  font-family:"Segoe UI","PingFang SC","Microsoft YaHei",system-ui,-apple-system,sans-serif;
  font-size:16px;}
img,svg{max-width:100%;}
a{color:var(--mark);text-decoration:none;}
a:hover{color:var(--mark-d);}
h1,h2,h3,h4{line-height:1.25;margin:0;color:var(--ink);}
p{margin:0 0 16px;}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px;}

/* ── Top nav ─────────────────────────────────────────────────────────────── */
.nav{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.94);
  backdrop-filter:saturate(160%) blur(8px);border-bottom:1px solid var(--line);}
.nav .wrap{display:flex;align-items:center;gap:16px;height:70px;max-width:none;padding:0 22px;}
/* The nav is sticky at 70px + its border, so an in-page jump has to stop short of
   it or the heading it was aimed at arrives underneath the bar. This is what the
   联系我们 button does on a company page — it stays on the page and scrolls. */
:target,section[id]{scroll-margin-top:90px;}
.brand{display:flex;align-items:center;gap:11px;color:var(--ink);}
.brand:hover{color:var(--ink);}
.brand img{display:block;width:38px;height:38px;}
.brand .name{font-weight:700;font-size:20px;letter-spacing:.1em;line-height:1.1;}
.brand .sub{display:block;font-size:12.5px;font-weight:600;color:var(--muted);letter-spacing:.34em;}
/* The nav is one level deep and shows where you are: the group's pages list the
   group, a company's pages list that company. No dropdown, so there is nothing
   to open, nothing to hover, and nothing that can render as a bulleted list on
   top of the bar if the stylesheet arrives late — the worst this can degrade to
   is a row of links, which is a menu. */
.navmenu{flex:1;display:flex;align-items:center;gap:2px;list-style:none;margin:0;padding:0;}
.navmenu > li:first-child{margin-left:auto;}
.navmenu > li{white-space:nowrap;}
.navmenu > li:nth-last-child(2){margin-left:auto;}
.navmenu a.navlink{display:inline-block;color:var(--muted);font-size:14.5px;font-weight:500;
  padding:8px 10px;border-radius:8px;}
.navmenu a.navlink:hover{color:var(--ink);background:var(--soft);}
.navmenu a.navlink.active{color:var(--mark);}

/* ── The trail ───────────────────────────────────────────────────────────────
   Shown only inside a company, because only there is there anywhere to go back
   to. It carries the group level that the bar gives up while you are down here. */
.crumbs{background:var(--soft);border-bottom:1px solid var(--line);font-size:13.5px;}
.crumbs .wrap{padding-top:10px;padding-bottom:10px;}
.crumbs a{color:var(--muted);}
.crumbs a:hover{color:var(--mark);}
.crumbs b{color:var(--ink);font-weight:600;}
.crumbs .sep{color:#c2c2c0;margin:0 8px;}
.langsel{font:inherit;font-size:13.5px;font-weight:600;color:var(--muted);background:var(--white);
  border:1px solid var(--line);border-radius:8px;padding:6px 8px;cursor:pointer;}
.langsel:hover{color:var(--mark);border-color:var(--mark);}
.nav-toggle{display:none;margin-left:auto;background:none;border:0;cursor:pointer;padding:8px;color:var(--ink);}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn{display:inline-block;border-radius:10px;padding:11px 21px;font-weight:600;font-size:15px;
  cursor:pointer;border:1px solid transparent;transition:background .12s,border-color .12s,color .12s;}
.btn-sm{padding:8px 15px;font-size:14px;}
.btn-primary{background:var(--mark);color:#fff!important;}
.btn-primary:hover{background:var(--mark-d);color:#fff!important;}
.btn-red{background:var(--red);color:#fff!important;}
.btn-red:hover{background:var(--red-d);color:#fff!important;}
.btn-ghost{background:transparent;border:1px solid rgba(255,255,255,.55);color:#fff!important;}
.btn-ghost:hover{background:rgba(255,255,255,.14);color:#fff!important;}
.btn-outline{background:var(--white);border:1px solid var(--line);color:var(--ink)!important;}
.btn-outline:hover{border-color:var(--mark);color:var(--mark)!important;}

/* ── Hero ──────────────────────────────────────────────────────────────────
   .subtitle is the line under the h1, in whatever language the page is. It was
   called .zh-title, and that name was the bug: a slot named for one language,
   in chrome shared by both, quietly invited Chinese onto the English pages —
   where it shipped, and a reader found it before the build did. build.py now
   audits the English output for exactly that (audit_english), and nothing in
   this file is named after a language any more.
   ──────────────────────────────────────────────────────────────────────── */
/* 默认每个 hero 都是集团渐变。曾经按 logo 的三个颜色分过：炭灰给制造、红给贸易。
   撤掉了，因为它区分不出任何东西——每家公司挂的是同一个 logo，读者没有线索
   把南宁和炭灰联系起来；而炭灰本来就是导航、按钮、页脚、正文在用的中性色，
   铺成整条 hero 就是一片近黑，不读作一个颜色。logo 第三个颜色是金 #F5D300，
   白字压在上面读不出来，hero 是白字排版，所以也用不了。
   --grad-mark 和 --grad-red 没有删，.segment 的色带和 .cn-stats 还在用。

   例外只有一个：深圳页用 .hero.sage，客户单独指定的灰绿。按色号命名而不是按
   页面或语义命名，是因为它就是一次颜色选择——北京同样是贸易公司，并没有跟着变。 */
.hero{background:var(--grad-group);color:#fff;padding:88px 0 92px;}
.hero.sage{background:var(--grad-sage);}
/* 灰绿最亮端是 #5a6e61，比集团渐变的红端亮。眉题与副标默认的 82% 白压在上面
   只有 4.3:1，差一点到 AA；提到 90% 是 4.8:1。只在这个 hero 里提，别处不动。 */
.hero.sage .eyebrow,.hero.sage .subtitle{color:rgba(255,255,255,.90);}
.hero .eyebrow{color:rgba(255,255,255,.82);}
.hero h1{font-size:44px;font-weight:700;color:#fff;letter-spacing:-.4px;margin-bottom:10px;}
.hero .subtitle{font-size:23px;font-weight:600;color:rgba(255,255,255,.82);letter-spacing:.14em;
  margin-bottom:18px;}
.hero p{font-size:17.5px;color:rgba(255,255,255,.93);max-width:660px;}
.hero .cta{display:flex;gap:14px;flex-wrap:wrap;margin-top:26px;}
/* Inner pages: a shorter band, same family. */
.pagehead{padding:56px 0 52px;}
.pagehead h1{font-size:36px;}

/* ── Sections ────────────────────────────────────────────────────────────── */
.section{padding:74px 0;}
.section.soft{background:var(--soft);}
.section.make-soft{background:var(--mark-soft);}
.section.trade-soft{background:var(--red-soft);}
.eyebrow{font-size:12.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--red);margin-bottom:10px;}
.eyebrow.v{color:var(--mark);}
.section h2{font-size:31px;margin-bottom:14px;}
.lead{font-size:17px;color:var(--muted);max-width:760px;}
.two{display:grid;gap:40px;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));align-items:start;}

/* ── Cards ───────────────────────────────────────────────────────────────── */
.cards{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));}
.cards.g2{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));}
.card{background:var(--white);border:1px solid var(--line);border-radius:var(--radius);
  padding:24px;box-shadow:var(--shadow);}
.card h3{font-size:18px;margin-bottom:8px;}
.card p{color:var(--muted);margin:0;font-size:15px;}
.card .more{display:inline-block;margin-top:14px;font-weight:600;font-size:14.5px;}
/* A card that belongs to one arm carries its colour as a top rule. */
.card.v{border-top:3px solid var(--mark);}
.card.o{border-top:3px solid var(--red);}

/* ── .flow — a sequence, drawn as one ─────────────────────────────────────
   For content that IS ordered and was being shown as a row of pills, which reads
   as an unordered set and throws the order away. Two places use it: the six
   process steps on 技术能力, and the four hands a product passes through on its
   way out of the group.

   Two states and no broken middle. Wide: one row, arrows between. Narrow: one
   column, arrows turned down. Nothing in between, because a wrapped row puts an
   arrow at the end of each line pointing into the margin — the usual way this
   component goes wrong.

   grid-auto-flow:column rather than auto-fit columns, so the row is the row
   whatever the item count: six here, four there, and no per-page arithmetic. */
.flow{list-style:none;margin:0;padding:0;display:grid;gap:26px;counter-reset:flow;}
.flow > li{counter-increment:flow;position:relative;text-align:center;
  background:var(--white);border:1px solid var(--line);border-radius:var(--radius);
  padding:20px 14px;box-shadow:var(--shadow);font-weight:600;}
.flow > li::before{content:counter(flow,decimal-leading-zero);display:block;
  font-size:11.5px;font-weight:700;letter-spacing:.14em;color:var(--mark);
  opacity:.5;margin-bottom:7px;}
.flow > li b{display:block;font-weight:700;}
.flow > li span{display:block;margin-top:5px;font-size:13.5px;font-weight:400;color:var(--muted);}
/* The arrow sits in the gap, not in the box, so it cannot shift the text. */
.flow > li::after{content:"";position:absolute;width:9px;height:9px;
  border-top:2px solid var(--mark);border-right:2px solid var(--mark);opacity:.4;
  left:50%;bottom:-19px;transform:translateX(-50%) rotate(135deg);}
.flow > li:last-child::after{content:none;}
/* On paper a six-across row is a squeeze; the sequence is what matters, not the
   direction it runs in. */
@media print{.flow{grid-auto-flow:row;gap:14px;}.flow > li::after{content:none;}}

/* The band under a .flow. MES is not a seventh step — it is a layer over all six,
   and drawing it as a step would say the opposite. So it is a bar that SPANS the
   row, with a tick at each end to show what it spans: the shape carries the claim,
   and the paragraph below it no longer has to. */
.flow__span{position:relative;margin-top:20px;padding:11px 18px;border-radius:999px;
  background:var(--mark-soft);border:1px solid var(--line);text-align:center;
  font-size:13.5px;font-weight:600;color:var(--mark);}
.flow__span::before,.flow__span::after{content:"";position:absolute;top:-10px;
  width:2px;height:10px;background:var(--line);}
.flow__span::before{left:26px;}
.flow__span::after{right:26px;}
/* Stacked, the column already reads top to bottom and a bracket across one narrow
   column says nothing, so the ticks go and it is simply a labelled strip. */
@media (max-width:859px){.flow__span::before,.flow__span::after{content:none;}}

@media (min-width:860px){
  /* Equal columns: six cells of one object should have one width and one set of
     edges, not six widths decided by how long each word happens to be. */
  .flow{grid-auto-flow:column;grid-auto-columns:1fr;gap:0 30px;align-items:stretch;}
  .flow > li::after{left:auto;right:-20px;bottom:auto;top:50%;
    transform:translateY(-50%) rotate(45deg);}
}

/* ── .world — where the group is, and where the product goes ──────────────
   STILL NOT A MAP. No coastline, no landmass, no border — dots at approximate
   bearings with their names beside them. Every real world outline draws Taiwan as
   a country in its own colour, separate from China, and putting one on a Chinese
   company's own site would be a 问题地图 at the largest scale there is. Nothing
   here asserts a boundary, so nothing here can get one wrong.

   Pacific-centred, the way a Chinese world map is: Africa left, China centre,
   South America right — the order the goods travel in, west and east out of the
   same three cities.

   CHINA IS THE SUBJECT, so it is the largest thing in the frame and the group's
   own three companies are CARDS while everything else is a mark and a name. That
   is the distinction doing the work: a filled dot and a ring tell two things
   apart, a card and a bare label tell them apart across the room.

   ONE DOM, TWO LAYOUTS. Below 820px the bearings stop meaning anything, so
   position goes away and the same blocks stack by region. */
.m{display:inline-flex;align-items:center;gap:8px;font-size:14.5px;color:var(--muted);}
.m::before{content:"";width:10px;height:10px;border-radius:50%;flex:0 0 auto;}
.m--own::before{background:var(--mark);}
/* Three companies, three colours, so one swatch cannot stand for them: the key
   shows all three. Which is which is on the cards themselves, next to their names. */
.m--own3::before{content:none;}
.m--own3 i{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:4px;}
.m--own3 i:nth-child(1){background:var(--yellow-d);}
.m--own3 i:nth-child(2){background:var(--mark);}
.m--own3 i:nth-child(3){background:var(--red);}
.m--own3{gap:4px;}
.m--cust::before{border:2px solid var(--red);}

.world{position:relative;display:grid;gap:26px;}
.world__lines,.world__cnlines{display:none;}
.world__spot{text-align:center;}
.world__spot > b{display:block;font-size:15.5px;font-weight:700;}
.world__spot .cust{display:block;font-size:13.5px;line-height:1.55;margin-top:3px;color:var(--muted);}
.world__spot .cust::before{content:"";display:inline-block;width:9px;height:9px;
  border-radius:50%;border:2px solid var(--red);margin-right:7px;vertical-align:1px;}
/* The key belongs to the picture, so it sits in the picture — at width it goes in
   the empty north-west corner, which no market occupies. */
.world__key{display:flex;flex-wrap:wrap;gap:8px 24px;justify-content:center;
  font-size:13.5px;}

.world__cn{position:relative;display:grid;gap:10px;justify-items:center;margin-top:10px;}
.wn{display:block;font-size:13.5px;line-height:1.4;}
.wn .d{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:7px;
  vertical-align:1px;}
.wn .d--own{background:var(--mark);}
.wn .d--cust{border:2px solid var(--red);}
.wn > b{font-weight:700;font-size:14.5px;}
.wn > em,.wn > u{font-style:normal;text-decoration:none;color:var(--muted);margin-left:6px;}
/* 集团总部 — which of the three it is, said on the card rather than in a footnote.
   Set as an eyebrow rather than coloured: it has to be readable, and the card's own
   hue is on the edge above it where legibility is not the job. */
.wn > u{color:var(--ink);font-weight:700;font-size:11.5px;letter-spacing:.08em;}

@media (min-width:820px){
  .world{display:block;position:relative;aspect-ratio:16/7;max-width:960px;margin:0 auto;}
  .world__lines{display:block;position:absolute;inset:0;width:100%;height:100%;}
  .world__lines path{fill:none;stroke:var(--red);stroke-width:2;stroke-dasharray:6 7;
    opacity:.4;vector-effect:non-scaling-stroke;}
  /* Charcoal, not red: these three lines are a relationship inside the group, and
     the four red ones leaving the panel are trade. Same dash, different claim. */
  .world__cnlines path{fill:none;stroke:var(--mark);stroke-width:2;stroke-dasharray:5 6;
    opacity:.3;vector-effect:non-scaling-stroke;}
  .world__spot{position:absolute;transform:translate(-50%,-50%);width:max-content;
    max-width:19ch;}
  .world__spot--sa{left:27%;top:42%;}
  .world__spot--sea{left:36%;top:82%;}
  .world__spot--af{left:12%;top:58%;}
  .world__spot--sam{left:92%;top:82%;}
  .world__key{position:absolute;left:14%;top:88%;transform:translate(-50%,-50%);
    display:grid;gap:7px;justify-items:start;}

  /* The panel. Sized for the ENGLISH labels — "Chengming Yingshi" and "Hong Kong,
     China" are half again the width of 诚明英视 and 中国香港, and a panel sized for
     the Chinese runs Taiwan off the right edge in the English edition only, which
     nothing in the build would have caught. */
  .world__spot--cn{left:60%;top:44%;max-width:none;}
  .world__spot--cn > b{font-size:17px;margin-bottom:6px;}
  .world__cn{display:block;width:470px;height:250px;margin:0 auto;
    border:1px dashed var(--line);border-radius:12px;background:var(--mark-soft);}
  /* The triangle between the three own companies — it was there when this was its
     own section and went missing when the panel was rebuilt. Behind the cards, so
     each line runs between them rather than across them. */
  .world__cnlines{display:block;position:absolute;inset:0;width:100%;height:100%;}
  .wn{position:absolute;left:var(--x);top:var(--y);transform:translate(-50%,-50%);
    white-space:nowrap;}
  .wn .d{display:block;margin:0 auto 5px;}
  .wn > b{display:block;}
  .wn > em,.wn > u{display:block;margin-left:0;font-size:12.5px;}
  /* A card, not a dot: the group's own companies read as objects, the markets as
     marks. This is the "different background" the distinction was missing. */
  /* One colour each, from the mark, assigned by what the company DOES rather than
     by taste: Nanning charcoal because charcoal is making things everywhere else on
     this site, Shenzhen red because red is trade, and Beijing the mark's yellow —
     the third colour for the one that is neither, which is what a headquarters is.
     Carried on the top edge and the dot; the label stays ink, because #D8BC00 text
     on white is unreadable and a colour that has to be legible as text is the wrong
     place to put a brand hue. */
  .wn--own{background:var(--white);border:1px solid var(--line);border-top:3px solid var(--c);
    border-radius:9px;padding:9px 13px;box-shadow:var(--shadow);}
  .wn--own .d--own{background:var(--c);}
  .wn--bj{--c:var(--yellow-d);}
  .wn--nn{--c:var(--mark);}
  .wn--sz{--c:var(--red);}
  .wn--bj{--x:52%;--y:20%;}
  .wn--nn{--x:17%;--y:64%;}
  .wn--sz{--x:51%;--y:64%;}
  .wn--hk,.wn--tw{padding-top:3px;}
  .wn--hk{--x:80%;--y:80%;}
  .wn--tw{--x:87%;--y:34%;}
}

@media (prefers-reduced-motion:no-preference){
  .world__lines path,.world__cnlines path{animation:world-draw 1.1s ease-out backwards;}
}
@keyframes world-draw{from{opacity:0;}to{opacity:.4;}}
@media print{.world__lines path,.world__cnlines path{animation:none;}}

/* ── .funnel — 核心优势 ────────────────────────────────────────────────────
   Five capability layers, drawn as the company's own deck draws them: widest at
   the top (国内外综合客户服务能力, the broadest reach) tapering to the narrowest at
   the base (制造能力, the most specific). It was a row of five pills here, which
   threw the layering away and put five things on one level that are not on one
   level.

   The colour runs the site's own encoding rather than a decorative ramp: the base
   is the mark's charcoal because that layer is making things, the top is the
   mark's red because that layer is the customer, and the three between are the
   walk from one to the other. */
.funnel{list-style:none;margin:0 auto;padding:0;max-width:600px;counter-reset:fn;}
.funnel > li{counter-increment:fn;position:relative;margin:0 auto 9px;padding:15px 22px;
  text-align:center;color:#fff;font-weight:600;font-size:15.5px;border-radius:7px;}
.funnel > li::before{content:counter(fn);position:absolute;left:12px;top:50%;
  transform:translateY(-50%);font-size:12px;font-weight:700;opacity:.55;}
.funnel > li:nth-child(1){width:100%;background:#ee2c29;}
.funnel > li:nth-child(2){width:87%;background:#a93330;}
.funnel > li:nth-child(3){width:74%;background:#5c4340;}
.funnel > li:nth-child(4){width:61%;background:#353536;}
.funnel > li:nth-child(5){width:48%;background:#1b1b1f;}
@media (max-width:560px){.funnel > li{width:100% !important;}}

@media (prefers-reduced-motion:no-preference){
  .funnel > li{animation:fn-in .5s ease-out backwards;}
  .funnel > li:nth-child(1){animation-delay:.04s;}
  .funnel > li:nth-child(2){animation-delay:.11s;}
  .funnel > li:nth-child(3){animation-delay:.18s;}
  .funnel > li:nth-child(4){animation-delay:.25s;}
  .funnel > li:nth-child(5){animation-delay:.32s;}
}
@keyframes fn-in{from{opacity:0;transform:translateY(-10px);}}
@media print{.funnel > li{animation:none;}}

/* ── .meters — a product line and how much of it ───────────────────────────
   The four electronics lines were named twice on the same page: once as pills in
   the segment card, once again in a capacity list below it. One object now, so
   each line is named once and carries its own figure.

   THE BARS ARE DRAWN FROM THE REAL NUMBERS AND LABELLED WITH THE APPROXIMATE
   ONES. Drawing them from the rounded-down floors would have made 机顶盒 and
   光猫与路由器 the same length when one is a fifth larger — the blurring is for the
   reader's eye on the text, not a licence to draw a false ratio. No axis and no
   figures on the bars, because the bars are there for the comparison and the words
   are there for the amount. */
.meters{list-style:none;margin:0;padding:0;}
.meters > li{padding:11px 0;border-bottom:1px solid var(--line);}
.meters > li:last-child{border-bottom:none;}
.meters b{font-weight:600;font-size:14.5px;}
.meters span{float:right;font-size:13.5px;color:var(--muted);}
.meters i{display:block;clear:both;height:6px;border-radius:999px;margin-top:9px;
  width:var(--v);background:var(--mark);opacity:.8;}
@media (prefers-reduced-motion:no-preference){
  .meters i{animation:meter-grow .8s cubic-bezier(.2,.7,.3,1) backwards;animation-delay:.15s;}
}
@keyframes meter-grow{from{width:0;}}
@media print{.meters i{animation:none;}}

/* ── 集团发展历程 — the staircase ──────────────────────────────────────────
   Five stages that climb left to right, after the company's own deck. THE RISE IS
   THE INFORMATION: each step stands on the one before it, which is the one thing a
   row of equal cards cannot say. The colour climbs with it, charcoal to red — the
   mark's ring to the mark's folded corner — so the company's history runs between
   its own two colours.

   Below 900px the staircase becomes a list: a five-column climb on a phone is four
   columns of nothing. The offsets therefore live inside the min-width query rather
   than being undone by one. */
.stair{list-style:none;margin:0;padding:0;display:grid;gap:20px;}
.stair > li{position:relative;padding-left:22px;--step:var(--mark);}
.stair > li::before{content:"";position:absolute;left:4px;top:14px;bottom:4px;width:2px;
  background:linear-gradient(var(--step),transparent);opacity:.45;}
.stair > li::after{content:"";position:absolute;left:0;top:4px;width:10px;height:10px;
  border-radius:50%;background:var(--step);}
.stair .tag{font-size:13px;font-weight:700;letter-spacing:.06em;color:var(--step);}
.stair .year{display:inline-block;margin:7px 0 11px;padding:9px 17px;border-radius:9px;
  background:var(--step);color:#fff;font-weight:700;font-size:17px;letter-spacing:.02em;}
.stair p{margin:0;color:var(--muted);font-size:15px;}
.stair > li:nth-child(1){--step:#353536;}
.stair > li:nth-child(2){--step:#5c4340;}
.stair > li:nth-child(3){--step:#8b3a35;}
.stair > li:nth-child(4){--step:#bc3130;}
.stair > li:nth-child(5){--step:#ee2c29;}

@media (min-width:901px){
  .stair{grid-template-columns:repeat(5,1fr);align-items:end;gap:18px;}
  /* align-items:end puts every step on the floor; the margin lifts it off again. */
  .stair > li:nth-child(2){margin-bottom:38px;}
  .stair > li:nth-child(3){margin-bottom:76px;}
  .stair > li:nth-child(4){margin-bottom:114px;}
  .stair > li:nth-child(5){margin-bottom:152px;}
}

/* Each step arrives a beat after the one below it — the climb, performed once.
   The rest state is the visible one: with animations off, or reduced motion asked
   for, every step is simply there. Nothing here is parked at opacity 0 waiting. */
@media (prefers-reduced-motion:no-preference){
  .stair > li{animation:stair-rise .55s cubic-bezier(.2,.7,.3,1) backwards;}
  .stair > li:nth-child(1){animation-delay:.03s;}
  .stair > li:nth-child(2){animation-delay:.11s;}
  .stair > li:nth-child(3){animation-delay:.19s;}
  .stair > li:nth-child(4){animation-delay:.27s;}
  .stair > li:nth-child(5){animation-delay:.35s;}
}
/* Paper has no first frame to animate into: a printed page must never catch a step
   mid-rise, and a staircase on paper is just a list that climbs. */
@media print{
  .stair > li{animation:none;}
  .stair{grid-template-columns:1fr;}
  .stair > li{margin-bottom:0;}
}
@keyframes stair-rise{from{opacity:0;transform:translateY(16px);}}

/* The three business segments, on the home page. */
.segment{display:block;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius);padding:0;overflow:hidden;box-shadow:var(--shadow);
  transition:box-shadow .15s,transform .15s;color:inherit;}
.segment:hover{box-shadow:var(--shadow-l);transform:translateY(-2px);color:inherit;}
.segment .band{height:6px;background:var(--grad-mark);}
.segment.o .band{background:var(--grad-red);}
.segment .body{padding:24px;}
.segment .num{font-size:12.5px;font-weight:700;letter-spacing:.16em;color:var(--mark);}
.segment.o .num{color:var(--red);}
.segment h3{font-size:19px;margin:6px 0 8px;}
.segment .sub{font-size:14px;color:var(--muted);font-weight:600;letter-spacing:.06em;}
.segment p{color:var(--muted);font-size:15px;margin:10px 0 0;}

/* ── Facts strip ─────────────────────────────────────────────────────────── */
.facts{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));}
.fact{border-left:3px solid var(--mark);padding-left:16px;}
.fact.o{border-left-color:var(--red);}
.fact .n{font-size:29px;font-weight:700;line-height:1.1;}
.fact .l{font-size:14px;color:var(--muted);margin-top:4px;}

/* ── Plain lists of specifics (equipment, models, certificates) ──────────── */
.chips{display:flex;flex-wrap:wrap;gap:8px;padding:0;margin:0;list-style:none;}
.chips li{background:var(--white);border:1px solid var(--line);border-radius:999px;
  padding:6px 14px;font-size:14px;color:var(--ink);}
.chips.v li{border-color:#dcdcda;}
.deflist{margin:0;}
.deflist dt{font-weight:600;font-size:14px;color:var(--muted);margin-top:16px;}
.deflist dd{margin:3px 0 0;font-size:16px;}

/* ── Photographs ─────────────────────────────────────────────────────────────
   Every photograph on this site came off the company's own existing website,
   where it was already published. They are small — 600px on the long edge for
   the equipment shots, less for the products — so the rule is: never scale one
   up past its native size, and give it a caption that says what it is. A
   blurry picture of a named machine is worth more than a sharp stock photo of
   somebody else's factory, but only if the reader is told which machine.

   .shot is one framed picture with its caption. .shotgrid lays several out and
   crops them to a common aspect so a row does not look ragged; .doc turns the
   crop off, for certificates, where cutting the edges off the document would
   be the one thing you must not do.
   ──────────────────────────────────────────────────────────────────────── */
.shot{margin:0;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow);}
.shot img{display:block;width:100%;height:auto;background:var(--soft);}
.shot figcaption{padding:11px 15px;font-size:14px;color:var(--muted);
  border-top:1px solid var(--line);line-height:1.5;}
.shot figcaption b{color:var(--ink);font-weight:600;}
.shotgrid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));}
.shotgrid .shot img{aspect-ratio:4/3;object-fit:cover;}
.shot.doc img{aspect-ratio:auto;object-fit:contain;background:#fff;padding:8px;}
.shotgrid.docs{grid-template-columns:repeat(auto-fit,minmax(170px,1fr));}

/* ── A frame whose photograph has not been taken yet ─────────────────────────
   Two background layers: the photograph OVATION will upload, and behind it the
   grey box it falls back to. CSS paints the list front to back and a layer that
   404s simply does not paint, so the frame shows the placeholder until the file
   exists and the photograph the moment it does — with no script, no build step
   and no markup change.

   It is a div rather than an <img> because only a background can do that, so it
   carries role="img" and aria-label in place of alt. The shape classes fix the
   aspect so the page does not reflow when the real picture lands.
   ──────────────────────────────────────────────────────────────────────── */
.ph-img{display:block;width:100%;background-size:cover;background-position:center;
  background-repeat:no-repeat;background-color:var(--soft);}
.ph-img.wide{aspect-ratio:3/2;}
.ph-img.tall{aspect-ratio:3/4;}
.ph-img.square{aspect-ratio:1/1;}
.ph-img.video{aspect-ratio:16/9;}
.ph-img.map{aspect-ratio:2/1;}
.ph-img.doc{aspect-ratio:5/7;background-size:contain;background-color:#fff;}
.shot.pending figcaption{color:#8f8f93;}
/* A real <img>, shaped like the .ph-img it replaced — a CSS background has no src
   for a crawler to fetch and no alt to read, and these two are the only
   photographs on the site. width/height are on the tag as well, so the caption
   does not jump when the picture arrives. */
.shot .doc-img{display:block;width:100%;height:auto;aspect-ratio:4/3;
  object-fit:contain;background:#fff;}
.shotgrid .shot .ph-img{aspect-ratio:4/3;}
.todo{display:block;margin-top:4px;font-size:12.5px;color:var(--red);}
.todo b{color:var(--red-d);font-weight:600;}

/* ── (Media placeholders lived here) ─────────────────────────────────────────
   Removed. Every missing photograph is now a real .jpg at its real path, drawn
   by _build/source/placeholders.py, so an empty slot is an <img> like any other
   and .shot.pending is all the styling it needs. That is what makes replacing
   one a single FTP overwrite on OVATION's own host, with no markup to edit.
   ──────────────────────────────────────────────────────────────────────── */
/* ── Customer logos ──────────────────────────────────────────────────────────
   Forty-eight marks at forty-eight different aspect ratios and weights. Left
   alone they read as a jumble, so: a fixed tile, the logo contained inside it
   with breathing room, and everything desaturated until hover. The grey is not
   a style choice — it is what stops a wall of other people's brand colours from
   competing with this site's own two.
   ──────────────────────────────────────────────────────────────────────── */
.logowall{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));}
.logowall .logo{display:flex;align-items:center;justify-content:center;
  background:var(--white);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;min-height:84px;}
.logowall .logo img{max-width:100%;max-height:54px;width:auto;height:auto;display:block;
  filter:grayscale(1);opacity:.72;transition:filter .15s,opacity .15s;}
.logowall .logo:hover img{filter:none;opacity:1;}
/* ── Contact ─────────────────────────────────────────────────────────────────
   Two equal columns, one per office. This was asymmetric when the right-hand
   column held an embedded enquiry form; the form was dropped in favour of plain
   contact details, so the two offices now carry equal weight.
   ──────────────────────────────────────────────────────────────────────── */
.contact{display:grid;gap:34px;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
  align-items:start;}

/* ── Notes to the people building this site ──────────────────────────────────
   Visible on the page ON PURPOSE while the site is unpublished: they say what
   is still missing and who owes it. Every one must be gone before launch —
   `grep -r "class=\"note\"" ovation/` is the check.
   ──────────────────────────────────────────────────────────────────────── */
.note{border-left:3px solid var(--red);background:var(--red-soft);
  padding:14px 18px;border-radius:0 10px 10px 0;font-size:14.5px;color:#7a2a28;margin:22px 0;}
.note b{color:#5e1f1d;}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.footer{background:var(--mark-deep);color:#c8c8c6;padding:48px 0 36px;font-size:14.5px;}
.footer a{color:#e8e8e6;}
.footer a:hover{color:#fff;}
.footer h4{color:#fff;font-size:15px;margin-bottom:12px;}
.footer .cols{display:grid;gap:30px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  padding-bottom:28px;border-bottom:1px solid rgba(255,255,255,.12);}
.footer ul{list-style:none;margin:0;padding:0;}
.footer li{margin-bottom:7px;}
.footer .legal{padding-top:22px;color:#9a9a9e;font-size:13.5px;
  display:flex;gap:16px;flex-wrap:wrap;justify-content:space-between;}
.footer .legal a{color:#9a9a9e;}

/* ── Narrow screens ──────────────────────────────────────────────────────── */
@media (max-width:860px){
  .hero{padding:60px 0 64px;}
  .hero h1{font-size:33px;}
  .hero .subtitle{font-size:19px;}
  .pagehead{padding:44px 0 40px;}
  .pagehead h1{font-size:28px;}
  .section{padding:52px 0;}
  .section h2{font-size:25px;}
  .contact{grid-template-columns:1fr;}
  .nav .wrap{height:auto;padding:12px 18px;flex-wrap:wrap;}
  .navmenu{gap:2px;flex-wrap:wrap;width:100%;}
  .navmenu > li:first-child,.navmenu > li:nth-last-child(2){margin-left:0;}
  .crumbs{font-size:13px;}
  .crumbs .sep{margin:0 6px;}
}

/* Site map — the list inside each .card on /sitemap/. .cards and .card do the
   rest; this is only the rows. */
.sitemap-list{list-style:none;margin:0;padding:0;}
.sitemap-list li{padding:7px 0;border-bottom:1px solid var(--line);}
.sitemap-list li:last-child{border-bottom:none;}
.sitemap-list a{font-size:15px;}

/* Key–value list — the licence facts on a company page. One rule: rows and a
   rule between them; everything else is the section it sits in. */
.kv{margin:0;}
.kv dt{font-size:13px;letter-spacing:.04em;color:var(--muted);margin-top:14px;}
.kv dt:first-child{margin-top:0;}
.kv dd{margin:3px 0 0;padding-bottom:12px;border-bottom:1px solid var(--line);}
.kv dd:last-child{border-bottom:none;}

/* Something on this page is not settled yet. Amber rather than red: nothing here
   is broken, it is waiting for an answer from the company — and it is meant to be
   seen by whoever can give that answer, not hidden in a document.
   Comes off with the review notes when NOTES is False. */
.ask{
  display:inline-block;font-size:12.5px;line-height:1.5;
  background:#fdf6d8;color:#6b5a00;border:1px solid #e0c33a;
  border-radius:4px;padding:1px 7px;margin:0 3px;vertical-align:baseline;
}
.ask b{color:#574800;}

