@import url("noto-sans.css?v=V2611131645");
/* Curly quotes ‘ ’ “ ” come from Noto Sans' Latin face: every CJK font (including a locally installed Noto Sans SC) draws them full-width,
   which tears English words like "let’s" apart. Only U+2018–201D use this face; everything else follows the spec's stack. */
@font-face { font-family: "Mega Latin Quotes"; font-style: normal; font-weight: 100 900; font-display: swap; src: url(fonts/noto-sans/notosans-o-0bIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjc5a7duw.woff2) format("woff2"); unicode-range: U+2018-201D; }

/* Typography spec (文字規範): Noto Sans CJK for every element.
   H1 48px / 36px, line-height 1.2 · H2 32px / 26px, 1.4 · subtitle 26px / 22px, 1.5 · body 16px / 16px (desktop / phone ≤767px).
   Display-size brand type (hero and footer wordmarks, 180px page titles, "Find Your Solution", 20+ stats) keeps its size;
   the industry carousel titles (農業 / 半導體 / …) are H1 and their descriptions are body text. */
:root {
  --mega-font: "Mega Latin Quotes", "Noto Sans TC", "Noto Sans SC", "Noto Sans JP", "Noto Sans KR", "Noto Sans", sans-serif;
  --mega-h1: 48px; --mega-h2: 32px; --mega-subtitle: 26px; --mega-body: 16px;
}
@media (max-width: 767px) {
  :root { --mega-h1: 36px; --mega-h2: 26px; --mega-subtitle: 22px; }
}
/* The page's side margin, as 「我們運用專業光譜分析技術…」 has it: .page-padding (30px, and 16px on every phone, up to 767px, where Webflow
   had it only up to 479px) either side of a centred .container of at most 1300px. Objects and copy laid against a screen edge keep
   this far in. site-navigation.js sets it in px from the page's width without the scrollbar; this is the same before it runs. */
:root { --mega-gutter: max(30px, (100vw - 1300px) / 2); }
@media (max-width: 767px) {
  :root { --mega-gutter: 16px; }
  .page-padding { padding-left: 16px; padding-right: 16px; }
}
/* Webflow redefines its typography variables on <body> at 991/767/479px (and on .nav-link-wrap), so map them there too. */
:root, body, .nav-link-wrap {
  --_typography---font-family: var(--mega-font);
  --_typography---font-size--heading-h1: var(--mega-h1);
  --_typography---font-size--heading-h2: var(--mega-h2);
  --_typography---font-size--body-s: var(--mega-body);
}
/* Colours (2026-11-09): the page's black ground is #151615 (--mega-bg; --mega-bg-rgb for see-through shades of it) and white text is
   #efefef (--mega-text). Webflow's own --black / --white (redefined on <body> and .section-2) follow them, so its body, links, nav and
   buttons do too; its --black-soft hairlines move up as much (#1a1a1a → #2c2d2c) so they still show on the lighter ground. Glows,
   lines, bars and icons stay white. */
:root { --mega-bg-rgb: 21 22 21; --mega-bg: rgb(var(--mega-bg-rgb)); --mega-text: #efefef; }
:root, body, .section-2 { --black: var(--mega-bg); --white: var(--mega-text); --black-soft: #2c2d2c; }
.dark-gradient { background-image: linear-gradient(180deg, var(--mega-bg), rgb(var(--mega-bg-rgb) / 0) 50%, var(--mega-bg)); }
.menu-bg-overlay { background-color: rgb(var(--mega-bg-rgb) / .9); }
.w-lightbox-backdrop, button, input, select, textarea { font-family: var(--mega-font); }
h1 { line-height: 1.2; }
h2 { line-height: 1.4; }
h3, .heading-subtitle, .text-block-6 { font-size: var(--mega-subtitle); line-height: 1.5; }
.body-text-2, .body-text-3, .video-text { font-size: var(--mega-body); }

/* Site-specific cleanup: remove only the Webflow badge and unused template links. */
.w-webflow-badge {
  display: none !important;
}

.footer-nav-wrap a[href="/template-pages/style-guide"],
.footer-nav-wrap a[href="/template-pages/license"] {
  display: none !important;
}

/* Global navigation — compact, high-contrast and readable over image-led pages. */
.navbar.w-nav {
  position: fixed !important;
  inset: 0 0 auto !important;
  z-index: 1000 !important;
  width: 100% !important;
  min-height: 0 !important;
  visibility: visible !important;
  background: transparent !important;
}
/* The bar's shade, on a layer of its own so it can fade by itself (display: block, as Webflow makes .w-nav::before a clearfix table). */
.navbar.w-nav::before { position: absolute; z-index: -1; inset: 0; display: block; content: ''; pointer-events: none; background: linear-gradient(180deg, rgb(var(--mega-bg-rgb) / .86), rgb(var(--mega-bg-rgb) / .38) 74%, transparent); transition: opacity .35s cubic-bezier(.4, 0, .2, 1); }
/* Scrolling down (site-navigation.js sets .mega-nav-hidden; scrolling up clears it): only the logo and the language globe go, lifted
   away by the standalone `translate` (which leaves the logo's centring transform alone) as they fade, and the shade fades with them.
   The menu button stays where it is, always at hand, with a soft shadow so its bars read over any picture. */
.navbar.w-nav .mega-nav-brand, .navbar.w-nav .mega-nav-shell > .mega-language { transition: translate .35s cubic-bezier(.4, 0, .2, 1), opacity .35s cubic-bezier(.4, 0, .2, 1), visibility 0s linear 0s; }
.navbar.w-nav.mega-nav-hidden::before { opacity: 0; }
.navbar.w-nav.mega-nav-hidden .mega-nav-brand, .navbar.w-nav.mega-nav-hidden .mega-nav-shell > .mega-language { translate: 0 -5.1rem; opacity: 0; visibility: hidden; pointer-events: none; transition: translate .35s cubic-bezier(.4, 0, .2, 1), opacity .35s cubic-bezier(.4, 0, .2, 1), visibility 0s linear .35s; }
.navbar.w-nav.mega-nav-hidden .mega-nav-toggle { filter: drop-shadow(0 0 .35rem rgb(0 0 0 / .65)); }
@media (prefers-reduced-motion: reduce) { .navbar.w-nav::before, .navbar.w-nav .mega-nav-brand, .navbar.w-nav .mega-nav-shell > .mega-language { transition: none !important; } }
.mega-nav-shell { display: flex; align-items: center; gap: 2.25rem; width: min(100% - 3rem, 1440px); min-height: 5.1rem; margin: 0 auto; }
.mega-nav-brand { display: flex; align-items: center; width: 11.2875rem; line-height: 1; text-decoration: none; }
.mega-nav-brand img { display: block; width: 100%; height: auto; max-height: 2.3625rem; object-fit: contain; object-position: left center; }
.mega-nav-links { display: flex; align-items: center; justify-content: flex-end; gap: 1.75rem; flex: 1; }
.mega-nav-links > a { position: relative; color: rgba(255,255,255,.86) !important; font-family: var(--mega-font); font-size: .88rem; font-weight: 600; letter-spacing: .04em; text-decoration: none; white-space: nowrap; transition: color .2s ease; }
.mega-nav-links > a:not(.mega-nav-cta)::after { position: absolute; right: 0; bottom: -.55rem; left: 0; height: 1px; content: ''; background: #dce8a3; transform: scaleX(0); transform-origin: left; transition: transform .2s ease; }
.mega-nav-links > a:hover, .mega-nav-links > a[aria-current="page"] { color: var(--mega-text) !important; }
.mega-nav-links > a:hover::after, .mega-nav-links > a[aria-current="page"]::after { transform: scaleX(1); }
.mega-nav-cta { padding: .7rem 1rem; border: 1px solid rgba(220,232,163,.8); color: #f9fce9 !important; }
.mega-nav-cta span { margin-left: .35rem; color: #dce8a3; }
.mega-language { position: relative; display: flex; align-items: center; }
/* The globe, the logo and the menu bars share one centre line, and the two ends mirror each other: the globe's drawn edge (the icon
   is drawn 32/512 in from its 1.5rem box) and the menu bars' outer edge (the button has .5rem padding) both sit the page's side
   margin (--mega-gutter) from the screen edge. Their panels mirror each other the same way: the language panel's left edge and the
   menu panel's right edge sit on that margin, and both tops hang .65rem below the globe (the menu panel: Navigation block below). */
.mega-nav-shell > .mega-language { position: absolute; left: calc(var(--mega-gutter) - 1.5rem * 32 / 512); margin: 0; }
.mega-nav-shell > .mega-language .mega-language-menu { right: auto; left: calc(1.5rem * 32 / 512); transform: none; }
.mega-language-toggle { display: grid; width: 1.5rem; height: 1.5rem; padding: 0; border: 0; background: transparent; cursor: pointer; place-items: center; }
.mega-language-toggle:hover, .mega-language-open .mega-language-toggle { background: transparent; }
.mega-language-toggle img { display: block; width: 100%; height: 100%; filter: invert(1); }
/* The language panel is set exactly like the menu panel (Navigation block below): subtitle-style items, the same margins, and
   1.2 times as wide as its items need (--panel-extra, site-navigation.js). */
.mega-language-menu { position: absolute; top: calc(100% + .65rem); right: 0; z-index: 2; width: max-content; padding: .925rem 8px; border: 1px solid rgba(220,232,163,.7); background: rgb(var(--mega-bg-rgb) / .97); box-shadow: 0 .75rem 2rem rgba(0,0,0,.3); }
.mega-language-menu button { display: block; width: 100%; padding: .65rem calc(.975rem + .75rem - 8px + var(--panel-extra, 0px)); border: 0; background: transparent; color: rgba(255,255,255,.86); font: 300 var(--mega-subtitle)/1.2 var(--mega-font); letter-spacing: normal; text-align: left; cursor: pointer; }
.mega-language-menu button:hover, .mega-language-menu button[aria-pressed="true"] { background: rgba(220,232,163,.16); color: var(--mega-text); }
.mega-nav-toggle { display: none; margin-left: auto; padding: .5rem; border: 0; background: transparent; cursor: pointer; }
.mega-nav-toggle i { display: block; width: 1.55rem; height: 1px; margin: .32rem 0; background: #fff; transition: transform .2s ease; }

/* Homepage title: keep the brand lockup at the top centre at every breakpoint. */
.hero_main .hero-heading-wrap { position: absolute; z-index: 2; top: clamp(6.5rem, 12vh, 10rem); left: 50%; width: min(100% - 2 * var(--mega-gutter), 82rem); margin: 0; transform: translateX(-50%); text-align: center; }
.hero_main .display-01.hero-title { width: 100%; margin-bottom: 0; text-align: center; }
.hero_main .hero-title-word { display: inline-block; white-space: nowrap; word-break: keep-all; overflow-wrap: normal; }
/* MEGA CRYSTAL is there from the first paint, without an entrance animation. Webflow's page-load timeline (IX3) would keep it hidden
   until its engine starts (the w-mod-ix3 rule in the page head) and then split it into letters and fade and slide each one up;
   the first rule outranks the head rule, the second holds every letter it makes visible and in place. */
html .hero_main .hero-heading-wrap .display-01.hero-title { visibility: visible !important; }
.hero_main .hero-title * { opacity: 1 !important; transform: none !important; }
.hero_main .hero-bottom { position: static; }
.hero_main .body-shape { display: none !important; }

/* Homepage crystal scroll scene. */
.mega-crystal-hero-track { position: relative; height: 240svh; background: var(--mega-bg); }
/* No margin: pinned from the first pixel of scroll (the crystal only grows, never slides up) and full-bleed so it can grow to the screen edges. */
.mega-crystal-hero-track .hero_main { position: sticky; top: 0; height: 100svh !important; margin: 0; overflow: hidden; background: var(--mega-bg); }
.mega-crystal-hero-track .hero-bg-image-wrap { opacity: 0; pointer-events: none; }
.mega-crystal-scroll { position: absolute; inset: 0; z-index: 3; overflow: hidden; background: transparent; pointer-events: none; }
.mega-crystal-scroll #stage { position: absolute; inset: 0; display: block; width: 100%; height: 100%; background: transparent; pointer-events: none; transform: translateY(-8%) scale(var(--crystal-scale, 1)); transform-origin: center; mix-blend-mode: screen; will-change: transform; }
.mega-crystal-blackout { position: absolute; inset: 0; z-index: 1; background: var(--mega-bg); opacity: var(--crystal-blackout, 0); pointer-events: none; }
.mega-crystal-hero-track .hero-heading-wrap { z-index: 2; opacity: var(--hero-title-opacity, 1) !important; color: var(--mega-text) !important; }
.mega-crystal-hero-track .hero-title, .mega-crystal-hero-track .hero-title-word { color: var(--mega-text) !important; opacity: 1 !important; }
/* The title sits under the crystal canvas (layer 3), but it is seen in front of the molecule: crystal-stage.js treats it as a plane
   facing the camera, first in front of every atom, and leaves the canvas transparent on the title's letters wherever the glass is
   behind that plane. Scrolling moves the plane back through the molecule, so the atoms pass through the title one after another. */
.mega-crystal-hero-track .page-padding.top { z-index: 2; }
.mega-crystal-hero-track .navbar { position: relative; z-index: 4; }
/* Hero title: fixed at the exact centre of the screen (does not move while scrolling); hidden once the scene has faded to black. */
@media (prefers-reduced-motion: no-preference) {
  .mega-crystal-hero-track .hero_main .hero-heading-wrap { position: fixed; top: 50%; transform: translate(-50%, -50%); pointer-events: none; visibility: var(--hero-title-visibility, visible); }
}

/* Scroll hint (site-navigation.js): bottom centre of the pinned hero, under the crystal. A mouse whose wheel dot rolls down (a bobbing
   chevron on touch screens) over a SCROLL label; fades out as the scene dives into the crystal (--scroll-hint-opacity). */
.mega-scroll-hint { position: absolute; z-index: 5; bottom: clamp(1.25rem, 3.5vh, 2.25rem); left: 50%; display: grid; justify-items: center; gap: .7rem; color: rgba(255, 255, 255, .8); opacity: var(--scroll-hint-opacity, 1); pointer-events: none; filter: drop-shadow(0 0 .4rem rgba(0, 0, 0, .65)); transform: translateX(-50%); transition: opacity .2s linear; }
.mega-scroll-hint-mouse { position: relative; display: block; width: 1.45rem; height: 2.3rem; box-sizing: border-box; border: 1.5px solid currentColor; border-radius: .75rem; }
.mega-scroll-hint-wheel { position: absolute; top: .4rem; left: 50%; width: .22rem; height: .45rem; margin-left: -.11rem; border-radius: .11rem; background: currentColor; animation: mega-scroll-wheel 1.8s cubic-bezier(.45, 0, .55, 1) infinite; }
.mega-scroll-hint-chevron { display: none; width: .8rem; height: .8rem; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; animation: mega-scroll-chevron 1.8s ease-in-out infinite; }
.mega-scroll-hint-label { margin-right: -.32em; font: 600 .68rem/1 var(--mega-font); letter-spacing: .32em; text-transform: uppercase; white-space: nowrap; }
/* 滾動進入網站 (and its Japanese / Korean): a touch larger, with less tracking. */
.mega-scroll-hint-label.is-cjk { margin-right: -.2em; font-size: .78rem; letter-spacing: .2em; }
/* The middle of the opening screen takes a click or a tap and enters the site (site-navigation.js .mega-hero-enter): an invisible
   button over the crystal and the title, clear of the navigation above and the scroll hint below; the site's cursor grows over it as
   over any button. */
.mega-hero-enter { position: absolute; z-index: 4; top: 50%; left: 50%; display: block; width: min(60vw, 52rem); height: min(56svh, 36rem); padding: 0; border: 0; background: transparent; translate: -50% -50%; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mega-hero-enter[hidden] { display: none; }
.mega-hero-enter:focus { outline: none; }
.mega-hero-enter:focus-visible { outline: 1px dashed rgba(255, 255, 255, .4); outline-offset: -6px; }
@media (max-width: 767px) { .mega-hero-enter { width: 88vw; height: 52svh; } }
@keyframes mega-scroll-wheel { 0% { opacity: 0; transform: translateY(0); } 20% { opacity: 1; } 70% { opacity: 1; transform: translateY(.7rem); } 100% { opacity: 0; transform: translateY(.7rem); } }
@keyframes mega-scroll-chevron { 0%, 100% { opacity: .4; transform: translateY(-.2rem) rotate(45deg); } 50% { opacity: 1; transform: translateY(.2rem) rotate(45deg); } }
@media (hover: none), (pointer: coarse) {
  .mega-scroll-hint-mouse { display: none; }
  .mega-scroll-hint-chevron { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .mega-scroll-hint-wheel, .mega-scroll-hint-chevron { animation: none; }
  .mega-crystal-hero-track { height: 100svh; }
  .mega-crystal-hero-track .hero_main { position: relative; }
  .mega-crystal-scroll #stage { transform: none; }
  .mega-crystal-blackout { opacity: 0; }
}
/* Phones: the molecule centred on the screen with the title. The camera aims at the molecule's centre of mass, whose outline sits
   6.3% of the canvas width right of it (and .44% of the height above it) on portrait screens: the canvas shifts back by that much,
   scaled with it, instead of the desktop lift; .92 keeps the whole molecule inside the screen width. crystal-stage.js measures the
   canvas's on-screen box, so the dive into the crystal still lands on the screen's centre. With reduced motion: no scaling. */
@media (max-width: 767px) {
  .mega-crystal-scroll #stage { --stage-scale: calc(var(--crystal-scale, 1) * .92); transform: translate(calc(var(--stage-scale) * -6.3%), calc(var(--stage-scale) * .44%)) scale(var(--stage-scale)); }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .mega-crystal-scroll #stage { --stage-scale: 1; }
}

/* Product page (產品與應用): the AI product advisor box takes the removed "/ APPLICATION · N. 01" top bar's place, without its divider line
   (title 80px · 20px · box), and sits 160px above the product cards.
   The title stays on one line: 180px on desktop, scaled with the screen where five characters would no longer fit. */
body:has(.b-project-wrap) .global-heading .display-01 { font-size: min(var(--_typography---font-size--display-xl), 18vw); }
/* Product cards in two columns (Webflow's three); phones keep Webflow's single column. Square photos, centred grid.
   Gaps are three times Webflow's (columns 18 → 54px, rows 40 → 120px, phones 20 → 60px). Each photo is 57.6% of the page width
   on phones and 28.8% (minus 7px) per column from 768px — the grid width below works that out with the 54px column gap.
   Product names are H2s set in Noto Sans Regular 22px (desktop and phone), centred under their photos. */
.b-project-wrap { width: 57.6%; margin-right: auto; margin-left: auto; grid-row-gap: 120px; }
.b-project-wrap .project-card-link { aspect-ratio: 1 / 1; height: auto; }
.b-project-wrap .project-info { justify-content: center; text-align: center; }
/* keep-all + <wbr> in the markup: one line when it fits, otherwise break only between phrases (no lone 「儀」). */
.project-info .mega-product-name { margin: 0; font: 400 22px/1.4 var(--mega-font); word-break: keep-all; overflow-wrap: anywhere; }
@media (min-width: 768px) { .b-project-wrap { width: calc(57.6% + 40px); grid-template-columns: repeat(2, minmax(0, 1fr)); grid-column-gap: 54px; } }
@media (max-width: 479px) { .b-project-wrap { grid-row-gap: 60px; } }
/* Product pages' "more products" carousel (assets/product-more.js; the user, 2026-11-13: 3 products, the middle one brightest, the two
   beside it darker, swipe to see the others). Every other product is in one looping row; three cards are in view: the centre one at
   full size and bright, the two beside it dimmed with their photos at 78% (about the photo's centre, so the names stay on one line),
   the rest out of sight. The cards share one grid cell (so the row is one card tall) and are moved by --offset × --step (the distance
   between card centres, which the script sets from the card width) plus --drag while being dragged. Webflow's fade-in on the cards is overridden: a card waiting out of sight would never get its turn.
   On phones the row runs edge to edge, so the side cards show at the screen edges. No dots underneath (the user, 2026-11-13). */
.mega-more { --card: min(26vw, 25rem); position: relative; overflow-x: clip; }
.mega-more .mega-more-track { display: grid; width: auto; grid-template-columns: var(--card); justify-content: center; gap: 0; touch-action: pan-y; cursor: grab; -webkit-user-select: none; user-select: none; }
.mega-more.is-dragging .mega-more-track { cursor: grabbing; }
.mega-more .mega-more-track > .w-dyn-item { --scale: 1; grid-area: 1 / 1; transform: translateX(calc(var(--offset, 0) * var(--step, 0px) + var(--drag, 0px))); transition: transform .6s cubic-bezier(.22, .61, .36, 1), opacity .6s ease; }
.mega-more .mega-more-track > .w-dyn-item .project-card-link { transform: scale(var(--scale)); transition: transform .6s cubic-bezier(.22, .61, .36, 1); }
.mega-more .mega-more-track > .is-side { --scale: .78; opacity: .35; }
.mega-more .mega-more-track > .is-away { --scale: .6; opacity: 0; pointer-events: none; }
.mega-more.is-dragging .mega-more-track > .w-dyn-item, .mega-more .mega-more-track > .is-jumping, .mega-more .mega-more-track > .is-jumping .project-card-link { transition: none; }
.mega-more .project-card { opacity: 1 !important; transform: none !important; }
/* Names are 84% of the card wide, so long ones (Japanese, English) wrap before they run into the next card's name. */
.mega-more .mega-product-name { max-width: 84%; }
/* Phones: the side cards only peek in at the screen edges, so their names (which would be cut into fragments) are hidden. */
@media (max-width: 767px) {
  .mega-more { --card: 54vw; margin-right: calc(50% - 50vw); margin-left: calc(50% - 50vw); }
  .mega-more .mega-more-track > .w-dyn-item .project-info { transition: opacity .6s ease; }
  .mega-more .mega-more-track > :not(.is-center) .project-info { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .mega-more .mega-more-track > .w-dyn-item, .mega-more .mega-more-track > .w-dyn-item .project-card-link { transition-duration: .01s; } }
.mega-product-search-bar { margin: 0 0 160px; padding: 20px 0 0; color: var(--mega-text); }
/* Centred pill-shaped box (no icon). */
.mega-product-search { position: relative; isolation: isolate; display: flex; align-items: center; width: min(100%, 30rem); height: 3.5rem; margin: 0 auto; padding: 0 1.75rem; box-sizing: border-box; border: 1px solid rgba(255, 255, 255, .16); border-radius: 999px; background: var(--mega-bg); }
/* Soft #98982a glow outside the box; it brightens while the advisor is answering. */
.mega-product-search::before { position: absolute; z-index: -1; inset: -1px; border-radius: inherit; content: ''; border: 1px solid #98982a; box-shadow: 0 0 1.1rem rgba(152, 152, 42, .7), 0 0 3rem rgba(152, 152, 42, .32); opacity: .9; pointer-events: none; transition: opacity .3s ease, filter .3s ease; }
.mega-product-search:hover::before, .mega-product-search:focus-within::before { opacity: 1; }
.mega-product-search.is-thinking::before { opacity: 1; filter: brightness(1.4); }
.mega-product-search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; background: transparent; color: var(--mega-text); font: 400 var(--mega-body)/1.2 var(--mega-font); letter-spacing: .04em; outline: none; }
.mega-product-search input::placeholder { color: rgba(255, 255, 255, .5); }
/* Advisor conversation (product-advisor.js): visitor messages as right-aligned bubbles; each answer = reply, recommended
   equipment (linking to the product pages), an optional follow-up question and a contact link (no needs summary since
   2026-11-12). It sits above the box like a chat (the user, 2026-11-12: 舊訊息要在輸入框上，可以滾動翻閱，不要無止盡的往下延伸):
   the log is at most min(34rem, 60vh) tall and scrolls on its own, newest at the bottom; its top 1.5rem fades out so messages
   scrolled up slip away softly (the padding keeps the first message clear of the fade). */
.mega-advisor { width: min(100%, 46rem); margin: 0 auto; text-align: left; }
/* Webflow centres every link (a { text-align: center }). */
.mega-advisor a { text-align: left; }
.mega-advisor-log { position: relative; display: grid; gap: 2rem; max-height: min(34rem, 60vh); margin: 0; padding: 1.5rem .5rem .5rem 0; overflow-y: auto; list-style: none; scrollbar-width: thin; scrollbar-color: rgba(220, 232, 163, .35) transparent; -webkit-mask-image: linear-gradient(transparent, #000 1.5rem); mask-image: linear-gradient(transparent, #000 1.5rem); }
.mega-advisor-user { justify-self: end; max-width: 80%; padding: .75rem 1.15rem; border-radius: 1.25rem 1.25rem .35rem 1.25rem; background: rgba(255, 255, 255, .09); color: var(--mega-text); font: 400 var(--mega-body)/1.6 var(--mega-font); white-space: pre-wrap; overflow-wrap: anywhere; }
.mega-advisor-reply { display: grid; gap: 1.1rem; color: rgba(255, 255, 255, .88); font: 400 var(--mega-body)/1.7 var(--mega-font); }
.mega-advisor-reply p { margin: 0; }
.mega-advisor-label { margin: 0 0 .4rem !important; color: #dce8a3; font: 600 .78rem/1.2 var(--mega-font); letter-spacing: .12em; }
.mega-advisor-products { display: grid; gap: .6rem; }
.mega-advisor-product { display: grid; grid-template-columns: 5rem minmax(0, 1fr) auto; align-items: center; gap: 1rem; padding: .6rem 1.1rem .6rem .6rem; border: 1px solid rgba(255, 255, 255, .14); border-radius: .9rem; color: var(--mega-text); text-decoration: none; transition: border-color .2s ease, background-color .2s ease; }
.mega-advisor-product:hover, .mega-advisor-product:focus-visible { border-color: rgba(220, 232, 163, .6); background: rgba(152, 152, 42, .14); }
.mega-advisor-product img { display: block; width: 5rem; height: 3.6rem; border-radius: .55rem; object-fit: cover; }
.mega-advisor-product strong { display: block; font-weight: 600; letter-spacing: .02em; }
.mega-advisor-product-reason { display: block; color: rgba(255, 255, 255, .7); font-size: .9rem; line-height: 1.55; }
.mega-advisor-product-arrow { color: #dce8a3; }
.mega-advisor-question { color: var(--mega-text); font-weight: 500; }
.mega-advisor-contact { justify-self: start; color: #dce8a3; text-decoration: none; border-bottom: 1px solid rgba(220, 232, 163, .5); }
.mega-advisor-contact:hover { color: var(--mega-text); border-color: #fff; }
.mega-advisor-note { color: rgba(255, 255, 255, .5); font-size: .85rem; }
.mega-advisor-error { color: #ffb4a8; }
.mega-advisor-thinking span { animation: mega-advisor-dot 1.2s ease-in-out infinite; }
.mega-advisor-thinking span:nth-child(2) { animation-delay: .2s; }
.mega-advisor-thinking span:nth-child(3) { animation-delay: .4s; }
@keyframes mega-advisor-dot { 0%, 80%, 100% { opacity: .2; } 40% { opacity: 1; } }
.mega-advisor-reset { display: block; margin: 1rem auto 1.5rem; padding: .5rem 1rem; border: 0; background: transparent; color: rgba(255, 255, 255, .55); font: 500 .85rem/1 var(--mega-font); letter-spacing: .06em; cursor: pointer; }
.mega-advisor-reset:hover, .mega-advisor-reset:focus-visible { color: var(--mega-text); }
@media (max-width: 767px) {
  .mega-advisor-user { max-width: 90%; }
  .mega-advisor-product { grid-template-columns: 4rem minmax(0, 1fr); padding-right: .9rem; }
  .mega-advisor-product img { width: 4rem; height: 3rem; }
  .mega-advisor-product-arrow { display: none; }
}
@media (prefers-reduced-motion: reduce) { .mega-advisor-thinking span { animation: none; opacity: 1; } }

/* Product detail pages (projects/*): two halves. The photo fills the left half and does not move while the page scrolls, until the
   right half ends; the right half — product name, the description under it, then the specification list — scrolls past it.
   The "/ SPECIFICATIONS · N. 01", "Final Result · N. 02" and "/ More Project · N. 03" top bars are removed.
   Phones stack everything in one column without pinning: photo, name, description, specifications. */
.mega-product-hero { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; column-gap: clamp(2rem, 5vw, 5rem); margin-bottom: 120px; }
/* Pinned from the first pixel of scroll: the sticky offset equals the photo's starting distance from the top of the page (the
   section's and container's --spacing-l top margins, which collapse into one). */
.mega-product-media { position: sticky; top: var(--spacing-l); }
.mega-product-hero .project-image-wrap { margin: 0; }
/* Never taller than the screen below that offset, so the whole photo stays in view while it is pinned. */
.mega-product-hero .projec-image-main { display: block; width: auto; max-width: 100%; height: auto; max-height: calc(100svh - var(--spacing-l) - 2rem); }
/* Display type scaled to the half column; keep-all breaks names only between words, unless one word is wider than the column. */
.mega-product-hero .mega-product-title { margin: 0 0 40px; font-size: min(7vw, 7.5rem); line-height: 1; letter-spacing: -.035em; text-align: left; word-break: keep-all; overflow-wrap: anywhere; }
.mega-product-hero .project-details-block { align-items: stretch; max-width: none; margin-left: 0; padding-bottom: 0; }
.mega-product-hero .heading-subtitle { margin: 0; text-align: left; }
/* Specification labels (型號, 適用產業, … 下載) in the left column of each row. */
.mega-product-hero .project-item .soft-text { color: var(--mega-text); font-weight: 700; }
@media (max-width: 991px) {
  .mega-product-hero { margin-bottom: 80px; }
}
@media (max-width: 767px) {
  .mega-product-hero { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .mega-product-media { position: static; }
  .mega-product-hero .projec-image-main { width: 100%; max-height: none; }
  .mega-product-hero .mega-product-title { font-size: min(var(--_typography---font-size--display-xl), 16vw); }
}
/* Turntable in place of the photo (product-turntable.js; MC-LIQ-C turns a full 360°): frames rendered from the 3D model on a
   transparent background. Dragging sideways with the mouse or a finger turns the device; there are no visible controls (the
   grab cursor only shows where the light cursor below is off). Vertical swipes and pinch zoom still reach the page on phones. */
.mega-turntable { cursor: grab; touch-action: pan-y pinch-zoom; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; outline: none; }
.mega-turntable.is-dragging { cursor: grabbing; }
.mega-turntable img { pointer-events: none; -webkit-user-drag: none; }
.mega-turntable:focus-visible { outline: 1px solid rgba(220, 232, 163, .6); outline-offset: 8px; }
/* The device shows at 80% of the photo's size, centred in the left column, with the 360° hint icon centred under it.
   The height cap leaves room for the icon so both stay in view while the column is pinned. */
.mega-product-hero .mega-turntable .projec-image-main { max-width: 80%; max-height: calc((100svh - var(--spacing-l) - 2rem) * .8); margin-inline: auto; }
.mega-turntable-hint { display: block; width: 4.5rem; margin: .75rem auto 0; color: rgba(255, 255, 255, .6); pointer-events: none; }
.mega-turntable-hint svg { display: block; width: 100%; height: auto; overflow: visible; }
@media (max-width: 767px) { .mega-product-hero .mega-turntable .projec-image-main { width: 80%; max-height: none; } }
@media (prefers-reduced-motion: reduce) { .mega-turntable-hint circle { display: none; } }

/* News list (最新消息): each item reads title, then the date under it, then the excerpt (Webflow puts the date first); the
   category shows only on the article page. The title starts level with the photo's top; "read more" keeps Webflow's size but is a frosted-glass button (the shared rule
   further down), with the same light sweep when its link is hovered. */
.collection-item-2 .div-block-25 { display: flex; flex-direction: column; }
.collection-item-2 .text-block-6 { order: -1; margin-top: 0; margin-bottom: var(--_typography---font-size--body-xs); }
/* Margins don't collapse in the flex column: the excerpt's own top margin (body-xl) is the only gap under the date. */
.collection-item-2 .div-block-27 { margin-bottom: 0; }
.collection-item-2 .text-block-9 { position: relative; isolation: isolate; overflow: hidden; }
/* The excerpt shows two lines, ending in "…" when it runs longer (the full text is on the article page). Webflow's clearfix
   pseudo-elements would count as lines in the clamped box. The paragraph's 10px bottom margin moves onto the box (10 + 10px), so
   the gap above "read more" stays 20px whether the text is cut or not. */
.collection-item-2 .rich-text-block { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; margin-bottom: 20px; }
.collection-item-2 .rich-text-block::before, .collection-item-2 .rich-text-block::after { content: none; }
.collection-item-2 .rich-text-block p { margin-bottom: 0; }
/* Category tabs (news-filter.js): plain white text. The picked tab is underlined and the others dim until hovered; with none
   picked every article shows and every tab is white. */
.mega-news-tab { padding: 0 0 4px; border: 0; border-bottom: 1px solid transparent; background: none; color: var(--mega-text); font: inherit; cursor: pointer; transition: color .2s ease, border-color .2s ease; }
.mega-news-tab[aria-pressed="true"] { border-bottom-color: var(--mega-text); }
.collection-list-wrapper:has(.mega-news-tab[aria-pressed="true"]) .mega-news-tab:not([aria-pressed="true"], :hover, :focus-visible) { color: rgba(255, 255, 255, .5); }
/* The tabs sit side by side in one row centred on the screen under the title at every width (Webflow floats them from the left,
   and stacks them below 768px). From 768px each keeps its column; below that each is as wide as its label, 2.5rem apart. */
.collection-list-wrapper:has(.mega-news-tab) .w-row { display: flex; justify-content: center; }
.collection-list-wrapper:has(.mega-news-tab) .w-row::before, .collection-list-wrapper:has(.mega-news-tab) .w-row::after { content: none; }
@media (max-width: 767px) {
  .collection-list-wrapper:has(.mega-news-tab) .w-col { width: auto; padding-right: 1.25rem; padding-left: 1.25rem; }
}
.collection-item-2[hidden] { display: none; }
.mega-news-empty { margin: 0; padding: 1.75rem 20px; color: rgba(255, 255, 255, .5); }
/* Load more under the news list (mega-site.js, 2026-11-12): the list shows the newest five articles and each press brings five
   more; the button goes once all are out. It is the glass button of Explore All / Get in Touch (the button block further down),
   centred under the list, in the user's own casing rather than uppercase. */
.mega-news-more-wrap { display: flex; justify-content: center; margin-top: clamp(3rem, 6vw, 5rem); }
.mega-news-more-wrap .mega-news-more { padding: 0; font-size: .9rem; letter-spacing: .08em; text-transform: none; cursor: pointer; }
/* Phones (where the photo stacks above the text): the title, date and excerpt span the photo's width, and "read more" sits on the
   left under them. */
@media (max-width: 479px) {
  .collection-item-2 .div-block-25 { padding-right: 0; padding-left: 0; }
  .collection-item-2 .form { text-align: left; }
}

/* Remove the "Find Your Solution / Get in Touch" promotional image section. */
.section:has(.cta-image-main) { display: none !important; }

/* Remove the homepage application-image gallery (the product page keeps its product list). */
.page-wrapper:has(.hero_main) .section-project { display: none !important; }

/* Homepage company section in one centred column: the (hidden) prism image and the empty ornament cell no longer hold the left 25%,
   so the heading spans the container and is centred on screen; it breaks at its comma when it does not fit on one line (the two
   phrases are inline-blocks, site-navigation.js). */
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .main-content { grid-template-columns: 100%; }
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .main-content > .about-img-wrap,
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .main-content > div:has(> .code-embed-5) { display: none; }
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .heading { text-align: center; text-wrap: balance; }
.mega-company-phrase { display: inline-block; }
/* Facts side by side across the heading's container (so they keep the same distance from the screen edges as the heading): 20+
   centred in the left half, 30+ centred in the right half, top-aligned so the figures share a line. padding-bottom extends the dark
   ground. */
.page-wrapper:has(.hero_main) .about-fact { display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(2rem, 8vw, 8rem); align-items: start; padding-bottom: 40px; }
.page-wrapper:has(.hero_main) .about-fact .fact-wrap { align-items: center; margin: 0; padding-inline: 0; text-align: center; transform: none; }
.page-wrapper:has(.hero_main) .about-fact .display-03 { align-self: center; }
/* The description is its own block so its wrapped lines are balanced (no lone 「合。」 on a last line). */
.page-wrapper:has(.hero_main) .about-fact .fact-text { max-width: 34rem; text-wrap: balance; }
.page-wrapper:has(.hero_main) .about-fact .soft-text { display: block; color: var(--mega-text); text-wrap: balance; }
/* Facts odometer (site-navigation.js): each digit is a one-line window onto a ribbon of digits; .is-rolled slides every ribbon to its
   last digit at once (3 s, slowing as it lands), then fades the "+" in. Tabular figures keep every digit the same width while rolling;
   the window clips only top and bottom (clip-path), so the figure's negative letter-spacing never cuts a digit's side. */
.mega-odometer { --odometer-duration: 3s; display: inline-flex; vertical-align: top; font-variant-numeric: tabular-nums; }
.mega-odometer-digit { display: block; height: 1lh; clip-path: inset(0 -.3em); }
.mega-odometer-ribbon { display: block; transition: transform var(--odometer-duration) cubic-bezier(.22, .61, .36, 1); }
.mega-odometer-ribbon > span { display: block; height: 1lh; }
.mega-odometer.is-rolled .mega-odometer-ribbon { transform: translateY(calc(var(--odometer-steps) * -1lh)); }
.mega-odometer-suffix { opacity: 0; transition: opacity .45s ease var(--odometer-duration); }
.mega-odometer.is-rolled .mega-odometer-suffix { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .mega-odometer-ribbon, .mega-odometer-suffix { transition: none; } }
/* 「我們運用專業光譜分析技術…」 has the same space above it (top padding, 20% more than the original clamp(6rem, 9vw, 8rem)) and below it, down
   to the facts (the grid's row gap takes the same value at every width). */
.page-wrapper:has(.hero_main) .section:has(.main-content) .container.padding-top { padding-top: clamp(7.2rem, 10.8vw, 9.6rem); }
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .main-content { row-gap: clamp(7.2rem, 10.8vw, 9.6rem); }
.page-wrapper:has(.hero_main) .section:has(.main-content) .container.padding-top { padding-bottom: calc(var(--spacing-xl) / 2); }
.page-wrapper:has(.hero_main) .section:has(.main-content) { position: relative; isolation: isolate; overflow-x: clip; }
/* Except the expertise section, which holds the 非接觸 pin (position: sticky). Safari (WebKit, so every browser on an iPhone) hands a
   sticky box to its compositor only when no ancestor clips overflow; under a clipping ancestor it moves the box on the main thread,
   behind the scroll, so on iPhones the pinned scene ran up with the finger and was pulled back down, over and over, for as long as it
   played (2026-11-11, iPhone 15 Pro). The hero and the industry stage, whose ancestors clip nothing, never shook. So this section
   clips nothing and the pin clips its own sides instead (.mega-brain-pin, below; the ring's and the scan dots' canvases are wider than
   a phone), which WebKit does not count. */
.page-wrapper:has(.hero_main) .section:has(.mega-brain) { overflow-x: visible; }
/* One static olive atmosphere under the company section and the expertise section after it (site-navigation.js wraps both in
   .mega-company-ground), so there is no seam between them: glows alternate right / left down the whole ground (about three screens),
   with one centred on the old boundary (≈37% down). Vertical sizes are % of the whole ground. */
.mega-company-ground { position: relative; background: radial-gradient(ellipse 78% 16% at 96% 1%, rgba(152, 152, 42, .64) 0%, rgba(91, 91, 25, .3) 48%, transparent 80%), radial-gradient(ellipse 46% 23% at 82% 5%, rgba(152, 152, 42, .28) 0%, transparent 72%), radial-gradient(ellipse 82% 20% at 3% 19%, rgba(152, 152, 42, .62) 0%, rgba(91, 91, 25, .3) 48%, transparent 80%), radial-gradient(ellipse 52% 25% at 15% 22%, rgba(152, 152, 42, .28) 0%, transparent 72%), radial-gradient(ellipse 84% 20% at 96% 38%, rgba(152, 152, 42, .64) 0%, rgba(91, 91, 25, .31) 48%, transparent 80%), radial-gradient(ellipse 48% 26% at 83% 35%, rgba(152, 152, 42, .29) 0%, transparent 72%), radial-gradient(ellipse 82% 21% at 3% 64%, rgba(152, 152, 42, .62) 0%, rgba(91, 91, 25, .3) 48%, transparent 80%), radial-gradient(ellipse 52% 27% at 15% 68%, rgba(152, 152, 42, .28) 0%, transparent 72%), radial-gradient(ellipse 86% 19% at 96% 97%, rgba(152, 152, 42, .66) 0%, rgba(91, 91, 25, .32) 48%, transparent 80%), radial-gradient(ellipse 48% 27% at 83% 90%, rgba(152, 152, 42, .3) 0%, transparent 72%), var(--mega-bg); }
/* Neither end of the ground shows a hard line: it fades in from black at the top (under the hero's black end) and back to black at
   the bottom (where the black film curtain rises over it). The fades lie under the two sections' content. */
.mega-company-ground::before, .mega-company-ground::after { position: absolute; z-index: 0; left: 0; right: 0; height: clamp(14rem, 45vh, 28rem); content: ''; pointer-events: none; }
.mega-company-ground::before { top: 0; background: linear-gradient(var(--mega-bg), rgb(var(--mega-bg-rgb) / .85) 20%, rgb(var(--mega-bg-rgb) / .5) 50%, rgb(var(--mega-bg-rgb) / .15) 80%, rgb(var(--mega-bg-rgb) / 0)); }
.mega-company-ground::after { bottom: 0; background: linear-gradient(rgb(var(--mega-bg-rgb) / 0), rgb(var(--mega-bg-rgb) / .15) 20%, rgb(var(--mega-bg-rgb) / .5) 50%, rgb(var(--mega-bg-rgb) / .85) 80%, var(--mega-bg)); }
.mega-company-ground > .section { z-index: 1; }
.page-wrapper:has(.hero_main) .section:has(.main-content) .main-content { position: relative; z-index: 1; }
.mega-eclipse { --eclipse-scale: 1; --eclipse-rotation: 0deg; --eclipse-intensity: 1; --eclipse-opacity: 0; --eclipse-y: 100vh; --eclipse-rgb: 255, 40, 40; --eclipse-rgb-hot: 255, 158, 158; position: absolute; z-index: 0; top: 53%; left: clamp(-35.2rem, -35.2vw, -28.8rem); width: clamp(57.6rem, 70.4vw, 70.4rem); aspect-ratio: 1; opacity: var(--eclipse-opacity); pointer-events: none; transform: translateY(-50%); transition: opacity .12s linear; }
/* The film section stacks above the sections before it. */
.page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) { position: relative; z-index: 3; }
/* Film section as a full-screen curtain: the embedded YouTube player is pinned to the screen and the section's clipped box rises over it
   from the bottom, holds it for half a screen, then the next section covers it from below. The clip also keeps the pinned player from
   catching clicks outside the section. Webflow's scroll animation on the wrapper is disabled because a transform there would stop it
   from being pinned. --film-gap-y keeps the 16:9 player clear of the fixed navigation (5.1rem) at the top; at the sides it keeps the
   page's side margin. */
.page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) { height: 150svh; padding: 0; clip-path: inset(0); }
.page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) .image-placeholder { --film-gap-y: 5.5rem; position: fixed; inset: 0; display: grid; place-items: center; width: 100%; height: 100svh; padding: var(--film-gap-y) var(--mega-gutter); background: var(--mega-bg); opacity: 1 !important; transform: none !important; will-change: auto !important; }
.video-embed-wrap { width: min(100%, (100svh - 2 * var(--film-gap-y)) * 16 / 9); aspect-ratio: 16 / 9; }
.video-embed-wrap iframe { display: block; width: 100%; height: 100%; border: 0; }
/* The player sits in the middle of three rows, so it stays centred on screen with the phone-only rotate button hanging below it. */
.page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) .image-placeholder { grid-template-rows: 1fr auto 1fr; }
.page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) .video-embed-wrap { grid-row: 2; }
/* Full screen (the user, 2026-11-13: 「影片頁，影片變成全螢幕」): on a landscape screen the 16:9 player covers the whole screen, edge to
   edge (as big as it must be to leave no bar, the rest cropped, centred; the navigation floats over its top). On a portrait screen (a
   phone held upright) it keeps the screen's width as before: covering the height there would leave only a sliver of the picture. */
@media (min-aspect-ratio: 1 / 1) {
  .page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) .image-placeholder { padding: 0; overflow: hidden; }
  .page-wrapper:has(.hero_main) .section:has(.video-embed-wrap) .video-embed-wrap { position: absolute; grid-area: auto; top: 50%; left: 50%; width: max(100%, 100svh * 16 / 9); height: max(100svh, 100vw * 9 / 16); aspect-ratio: auto; translate: -50% -50%; }
}
/* Full screen (site-navigation.js) the player must take touches even if the section was mid-scroll (its inline pointer-events: none). */
.video-embed-wrap iframe:fullscreen { pointer-events: auto !important; }
.video-embed-wrap iframe:-webkit-full-screen { pointer-events: auto !important; }
.mega-film-rotate { display: none; }
@media (max-width: 767px) {
  /* Icon only, centred under the player (the placeholder grid centres its items); a 3rem square keeps it an easy tap target. */
  .mega-film-rotate { display: grid; grid-row: 3; align-self: start; justify-self: center; width: 3rem; height: 3rem; margin-top: 1.5rem; padding: 0; border: 0; background: transparent; color: var(--mega-text); cursor: pointer; place-items: center; -webkit-tap-highlight-color: transparent; }
  .mega-film-rotate:active { background: rgba(152, 152, 42, .18); }
  .mega-film-rotate svg { width: 1.5rem; height: 1.5rem; }
}
/* The fixed navigation lives inside the hero: lift the hero above the full-screen film (z-index 3) so the menu stays visible over it. */
.mega-crystal-hero-track .hero_main { z-index: 10; }
/* Pinned eclipse stays below the process section's path art (z-index 1) and steps (z-index 2): at double size it must not cover copy on phones. */
.mega-eclipse.is-pinned { position: fixed; z-index: 0; top: 0; transform: translate3d(0, var(--eclipse-y), 0); will-change: transform; }
.mega-eclipse-rays, .mega-eclipse-halo, .mega-eclipse-core { position: absolute; inset: 0; border-radius: 50%; }
.mega-eclipse-rays { display: none; }
/* Light ring (光圈): a bold white-hot line (.6rem) with a neon glow on both sides (softer and wider inside) and a clear centre.
   The ring sits 0.28× the box width from the centre = 35% of the halo gradient. Colour comes from --eclipse-rgb (rainbow over the scroll,
   set in site-navigation.js); the glow breathes in brightness (--eclipse-intensity) rather than size, so the two layers stay one ring. */
.mega-eclipse-halo { inset: -30%; opacity: calc(.95 * var(--eclipse-intensity)); background: radial-gradient(circle closest-side, transparent 12%, rgba(var(--eclipse-rgb), .05) 21%, rgba(var(--eclipse-rgb), .2) 29%, rgba(var(--eclipse-rgb-hot), .75) 33%, rgba(var(--eclipse-rgb-hot), .95) 34.6%, rgba(var(--eclipse-rgb), .7) 36.8%, rgba(var(--eclipse-rgb), .25) 43%, rgba(var(--eclipse-rgb), .07) 51%, transparent 62%); filter: blur(15px) brightness(.8); }
/* The white-hot line is softened by a blur of half its thickness (.3rem); both layers are dimmed to 80% brightness. */
.mega-eclipse-core { z-index: 1; inset: 22%; border: .6rem solid rgba(var(--eclipse-rgb-hot), .95); background: transparent; filter: blur(.3rem) brightness(.8); box-shadow: 0 0 1.2rem rgba(var(--eclipse-rgb-hot), .9), 0 0 4.2rem rgba(var(--eclipse-rgb), .8), 0 0 7rem rgba(var(--eclipse-rgb), .35), inset 0 0 1.2rem rgba(var(--eclipse-rgb-hot), .85), inset 0 0 4.8rem rgba(var(--eclipse-rgb), .55), inset 0 0 9rem rgba(var(--eclipse-rgb), .18); }

/* Footer contact details. */
.footer-top-wrap .phone-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; }
.footer-top-wrap .phone-wrap .line { display: none; }
.footer-top-wrap .mega-footer-email { color: inherit; text-decoration: none; }
.footer-top-wrap .mega-footer-email:hover { color: #dce8a3; }
.footer-top-wrap { position: relative; }
.footer-top-wrap .footer-nav-wrap { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.footer-top-wrap .footer-nav { white-space: nowrap; }
.footer-top-wrap > .align-right { display: none; }
.footer-top-wrap .social-icon-wrap { display: flex; align-items: center; gap: 1.25rem; }
.footer-top-wrap .mega-social-icon { display: grid; width: 1.25rem; height: 1.25rem; place-items: center; }
.footer-top-wrap .mega-social-icon img { display: block; width: 100%; height: 100%; filter: invert(1); transition: opacity .2s ease; }
.footer-top-wrap .mega-social-icon:hover img { opacity: .65; }
.bottom-content { padding-top: clamp(3.5rem, 6vw, 6rem) !important; }
.bottom-content .year,
.bottom-content .copyright-symb { display: none !important; }
/* Footer gradient, not boxed in: it fills the whole footer and fades to transparent at the top, so no straight edge or
   1px divider frames it. After the solution callout the footer box also starts min(9rem, 12vw) higher (negative margin +
   equal padding, content unmoved), so the glow rises into that section's empty bottom padding — always less than the
   padding, so it never reaches the button. The footer keeps Webflow's overflow: hidden, which also clips its slide-in animations.
   .mega-solution is transparent so the glow shows behind it. */
.footer-bg-image { top: 0 !important; bottom: auto !important; height: 100% !important; max-height: none !important; object-fit: cover; object-position: center bottom; overflow: hidden; -webkit-mask-image: linear-gradient(to bottom, transparent, #000 55%); mask-image: linear-gradient(to bottom, transparent, #000 55%); }
.mega-solution + .section-footer { margin-top: calc(-1 * min(9rem, 12vw)); padding-top: min(9rem, 12vw); }
/* Footer fluid gradient (site-navigation.js): the WebGL canvas sits exactly where the glow image is, with the same top fade, and the
   image is hidden only once the canvas has drawn. */
.mega-footer-ripple { position: absolute; z-index: -1; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; -webkit-mask-image: linear-gradient(to bottom, transparent, #000 55%); mask-image: linear-gradient(to bottom, transparent, #000 55%); }
.footer-bg-image.is-rippled { visibility: hidden; }
/* The glow is drawn on pure black: lightened over the page's ground (#151615), its dark corners become that ground. */
.footer-bg-image, .mega-footer-ripple { mix-blend-mode: lighten; }
/* Product photos (cards, product heroes) and the about page's year pictures are on pure black: each is lightened over the ground in a
   group of its own (isolation, with the ground as its background, so Webflow's entrance transforms cannot cut it off from it), so its
   near-black (JPEG noise of 2–4) becomes exactly #151615 and the objects stay as they are. */
.project-card-link, .mega-product-hero .project-image-wrap, .experience-wrap .experiencr-year { isolation: isolate; background-color: var(--mega-bg); }
.project-image, .mega-product-hero .projec-image-main, .experience-wrap .mega-year-image { mix-blend-mode: lighten; }

/* Mouse cursor as a small white light (site-navigation.js): a soft blurred centre on the pointer and, trailing it, a white haze over a
   wider pool that brightens what lies beneath (backdrop-filter, masked to fade out at the edge) so text and images light up as the mouse
   passes. Pure black stays black under the pool; the haze is what shows the light there. The native cursor is hidden only after the
   light has appeared; text fields keep theirs.
   2026-11-12 (the user: 滑鼠的光源擴散範圍縮小30%，亮度-20%): the haze and the pool are 70% of their old size (4rem → 2.8rem,
   8rem → 5.6rem; the centre keeps its size) and all three layers show at 80% (the pool's brightening 2.3 → 2.04 in effect). */
html.mega-cursor-on, html.mega-cursor-on * { cursor: none !important; }
html.mega-cursor-on :is(input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]), textarea, [contenteditable="true"]) { cursor: text !important; }
.mega-cursor-core, .mega-cursor-glow, .mega-cursor-light { position: fixed; z-index: 2147483000; top: 0; left: 0; border-radius: 50%; opacity: 0; pointer-events: none; will-change: translate; transition: opacity .25s ease, scale .25s ease; }
/* Soft centre: a blurred white haze, no crisp bright point. */
.mega-cursor-core { width: 1.8rem; height: 1.8rem; margin: -.9rem 0 0 -.9rem; background: radial-gradient(circle, rgba(255, 255, 255, .7), rgba(255, 255, 255, .42) 32%, rgba(255, 255, 255, .14) 62%, transparent 78%); filter: blur(4px); }
.mega-cursor-glow { width: 2.8rem; height: 2.8rem; margin: -1.4rem 0 0 -1.4rem; background: radial-gradient(circle, rgba(255, 255, 255, .2), rgba(255, 255, 255, .07) 40%, transparent 70%); mix-blend-mode: screen; }
.mega-cursor-light { width: 5.6rem; height: 5.6rem; margin: -2.8rem 0 0 -2.8rem; -webkit-backdrop-filter: brightness(2.3) saturate(1.15); backdrop-filter: brightness(2.3) saturate(1.15); -webkit-mask-image: radial-gradient(circle closest-side, #000 30%, rgba(0, 0, 0, .5) 62%, transparent); mask-image: radial-gradient(circle closest-side, #000 30%, rgba(0, 0, 0, .5) 62%, transparent); }
html.mega-cursor-visible :is(.mega-cursor-core, .mega-cursor-glow, .mega-cursor-light) { opacity: .8; }
html.mega-cursor-link .mega-cursor-core { scale: 1.4; }
html.mega-cursor-link :is(.mega-cursor-glow, .mega-cursor-light) { scale: 1.35; }
html.mega-cursor-pressed .mega-cursor-core { scale: .7; }
.footer-top-wrap { border-top: 0; }

/* Homepage process: black ground with the light ring (site-navigation.js), HTML nodes and a scroll-drawn SVG path. clip-path keeps the
   pinned (fixed) ring inside the section's box. */
.mega-spectrum-process { position: relative; isolation: isolate; min-height: clamp(94rem, 105.75vw, 127rem); overflow: clip; clip-path: inset(0); background: var(--mega-bg); color: var(--mega-text); }
/* The light ring's glow fades out towards the section's top and bottom edges instead of being cut off there in a straight line (the
   section clips the pinned ring; the user, 2026-11-12: 「光圈被切成一條直線」): a fade to the page's black, over the ring (z-index 0,
   site-navigation.js .mega-eclipse) and under the path (z-index 1, later) and the steps (z-index 2). */
.mega-spectrum-process::before, .mega-spectrum-process::after { position: absolute; left: 0; right: 0; display: block; height: clamp(8rem, 24vh, 16rem); content: ''; pointer-events: none; }
.mega-spectrum-process::before { top: 0; z-index: 1; background: linear-gradient(var(--mega-bg), rgb(var(--mega-bg-rgb) / .85) 25%, rgb(var(--mega-bg-rgb) / .45) 55%, rgb(var(--mega-bg-rgb) / .12) 80%, rgb(var(--mega-bg-rgb) / 0)); }
.mega-spectrum-process::after { bottom: 0; z-index: 0; background: linear-gradient(rgb(var(--mega-bg-rgb) / 0), rgb(var(--mega-bg-rgb) / .12) 20%, rgb(var(--mega-bg-rgb) / .45) 45%, rgb(var(--mega-bg-rgb) / .85) 75%, var(--mega-bg)); }
.mega-spectrum-art, .mega-spectrum-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.mega-spectrum-svg { overflow: visible; shape-rendering: geometricPrecision; }
.mega-spectrum-art { z-index: 1; pointer-events: none; }
.mega-spectrum-mobile { display: none; }
/* Each step sits on the beam as a crystal molecule photo (black background). The nodes layer blends with screen, so the black drops
   out over the light ring and only the glass shows. Nodes are offset by half the photo size
   (--spectrum-marker) so each photo's centre lands on its point of the beam. */
/* The empty band above the first step is 20% shorter: the art and nodes keep their full height (--spectrum-height, so every position
   along the path is unchanged) but sit --spectrum-lift higher, and the section is that much shorter. The lift is 20% of the space
   between the section top and the first molecule (node 1's centre at --spectrum-node1-y of the height, minus half a molecule). */
.mega-spectrum-process { --spectrum-marker: clamp(9.1rem, 11.7vw, 14.3rem); --spectrum-height: clamp(94rem, 105.75vw, 127rem); --spectrum-node1-y: .2384; --spectrum-lift: calc((var(--spectrum-height) * var(--spectrum-node1-y) - var(--spectrum-marker) / 2) * .2); min-height: calc(var(--spectrum-height) - var(--spectrum-lift)); }
.mega-spectrum-process .mega-spectrum-art, .mega-spectrum-process .mega-spectrum-nodes { top: calc(-1 * var(--spectrum-lift)); bottom: auto; height: var(--spectrum-height); }
/* Where the steps would reach past the page's side margin (wide screens), site-navigation.js draws the path and the steps in a
   narrower band: --spectrum-left / --spectrum-right in from the section's sides. On phones it sets the band that puts the steps'
   outer edges exactly at the margin (negative where the band is wider than the section). */
.mega-spectrum-process .mega-spectrum-art, .mega-spectrum-process .mega-spectrum-nodes { left: var(--spectrum-left, 0px); right: var(--spectrum-right, 0px); width: auto; }
.mega-spectrum-nodes { position: absolute; z-index: 2; inset: 0; margin: 0; padding: 0; list-style: none; mix-blend-mode: screen; }
.mega-spectrum-node { position: absolute; display: flex; align-items: center; gap: clamp(.9rem, 1.1vw, 1.3rem); color: var(--mega-text); }
/* text-wrap: balance evens out the lines, so a step never ends on a lone character or two (e.g. 「備。」). */
.mega-spectrum-node h2 { width: min(28rem, 26vw); margin: 0; font: 500 var(--mega-h2)/1.4 var(--mega-font); letter-spacing: 0; text-wrap: balance; }
/* --glow (0–1) is set while the travelling point of light passes: the glass brightens (black stays black) and a soft halo rises behind it. */
/* --lit (0–1): each molecule stays unseen until the point of light reaches it (site-navigation.js). */
.mega-spectrum-marker { --glow: 0; position: relative; display: block; width: var(--spectrum-marker); height: var(--spectrum-marker); flex: 0 0 auto; opacity: var(--lit, 0); }
.mega-spectrum-marker::before { position: absolute; inset: 8%; border-radius: 50%; content: ''; opacity: var(--glow); background: radial-gradient(circle, rgba(255, 252, 222, .5), rgba(220, 220, 140, .2) 45%, transparent 70%); }
.mega-spectrum-molecule { position: relative; display: block; width: 100%; height: 100%; object-fit: contain; filter: brightness(calc(1 + var(--glow) * 1.3)); }
/* The point of light that moves along the (invisible) path as you scroll, with a soft tail while moving (site-navigation.js).
   A large blurred glow (2.52rem core); site-navigation.js caps its opacity at 80%. */
.mega-spectrum-pulse, .mega-spectrum-pulse-trail { position: absolute; top: 0; left: 0; border-radius: 50%; opacity: 0; pointer-events: none; will-change: translate, opacity; }
.mega-spectrum-pulse { z-index: 1; width: 2.52rem; height: 2.52rem; margin: -1.26rem 0 0 -1.26rem; background: radial-gradient(circle, #fff 0 30%, #fffde6 55%, rgba(255, 253, 230, 0)); box-shadow: 0 0 2.52rem .9rem rgba(255, 255, 240, .8), 0 0 8.7rem 3.3rem rgba(255, 252, 220, .32); filter: blur(9px); }
.mega-spectrum-pulse-trail { width: calc(2.22rem - var(--trail) * .21rem); height: calc(2.22rem - var(--trail) * .21rem); margin: calc(-1.11rem + var(--trail) * .105rem) 0 0 calc(-1.11rem + var(--trail) * .105rem); background: rgba(255, 253, 235, .75); box-shadow: 0 0 2.1rem .54rem rgba(255, 252, 220, .38); filter: blur(9px); }
.mega-spectrum-node-1 { left: calc(40.36% - var(--spectrum-marker) / 2); top: calc(23.84% - var(--spectrum-marker) / 2); }
.mega-spectrum-node-2 { left: calc(15.88% - var(--spectrum-marker) / 2); top: calc(44.53% - var(--spectrum-marker) / 2); }
.mega-spectrum-node-3 { left: calc(52.6% - var(--spectrum-marker) / 2); top: calc(66.2% - var(--spectrum-marker) / 2); }
.mega-spectrum-node-4 { left: calc(28.12% - var(--spectrum-marker) / 2); top: calc(87.88% - var(--spectrum-marker) / 2); }
/* The four steps sit 50px further right, and so does the light's path, so the point of light still passes through each molecule
   (the light ring stays where it is); steps 2–4 sit a further 50px right, and the point of light eases over to them between steps
   1 and 2 (site-navigation.js). Phones keep their own layout. */
@media (min-width: 768px) {
  .mega-spectrum-process .mega-spectrum-art, .mega-spectrum-process .mega-spectrum-nodes { translate: 50px 0; }
  .mega-spectrum-node-2, .mega-spectrum-node-3, .mega-spectrum-node-4 { translate: 50px 0; }
  /* The four sentences sit a further 50px right of their molecules (less below 1200px, none at 1000px, where step 3 would run off
     the screen). */
  .mega-spectrum-node h2 { translate: clamp(0px, (100vw - 1000px) / 4, 50px) 0; }
}
/* Step 1 in two set lines (研發實力堅強， / 可依客戶需求提供高度客製化設備。); where the second line has no room it wraps. */
@media (min-width: 1200px) {
  .mega-spectrum-node-1 h2 { width: max-content; }
}

/* Shared pre-footer solution callout. */
.mega-solution { display: grid; min-height: calc(100svh + 12rem); padding: clamp(9rem, 14vw, 14rem) var(--mega-gutter); box-sizing: border-box; background: transparent; color: var(--mega-text); place-content: center; text-align: center; }
.mega-solution-copy { --solution-free: 12.4vw; display: grid; gap: .02em; max-width: 18ch; font: 700 calc(clamp(4rem, var(--solution-free), 11.8rem) * var(--fit, 1))/.91 var(--mega-font); letter-spacing: -.075em; }
.mega-solution-line { padding: .05em .07em .08em; }
.mega-solution-line > span { display: block; }
.mega-solution-word { display: inline-block; white-space: nowrap; }
.mega-solution-mobile-break { display: none; }
.mega-solution-char { display: inline-block; font-style: normal; }
/* Noto Sans' word space is narrower than Arial's: keep the gap readable under the tight tracking. */
.mega-solution-space { margin-right: .06em; }
/* Fixed colours (the user, 2026-11-12: 「Find Your Solution用白色 / Let's Innovate用#98982a」); the grey↔white scroll sweep is gone. */
.mega-solution-main .mega-solution-char { color: var(--mega-text); }
/* Chinese lines (探索解決方案 / 開啟創新契機, since 2026-11-13; Japanese and Korean translate them): no negative tracking (it would run
   the characters into each other) and no width cap, so each line stays whole on one line at every width (six characters at 15vw fit
   a phone). Japanese is set a phrase to a row (…を／…); a translation longer than 繁體中文 is set smaller as a block (--fit,
   site-navigation.js fitSolution). */
.mega-solution-copy.is-cjk { max-width: none; letter-spacing: .02em; }
/* …and never broken, not even the olive line on phones as English and Korean words would be (wrapped CJK rows at line-height .91
   run into each other): two lines, as in 繁體中文. */
.mega-solution-copy.is-cjk .mega-solution-line > span { white-space: nowrap; }
.mega-solution-copy.is-cjk .mega-solution-mobile-break { display: none; }
/* The hidden 繁體中文 copy at its size without the cap (--solution-free), measured for how wide a translation may be (fitSolution). */
.mega-text-reference .mega-solution-copy.is-uncapped { font-size: var(--solution-free); }
.mega-solution-soft .mega-solution-char { color: #98982a; }
/* Get in Touch: layout only — its outline/crystal hover is shared with Explore All (see the crystal buttons rules). */
.mega-solution-button { justify-self: center; margin-top: clamp(3.5rem, 8vw, 7rem); }
/* The original footer's hidden top padding made the solution section appear to have an oversized lower gap. */
.mega-solution + .section-footer .container.padding-top { padding-top: 0; }

/* Cinematic industry carousel placed directly below the homepage film. */
/* One screen, held while the page scrolls on, the industries changing with the scroll (the user, 2026-11-13: 「持續往下滑產業會隨著
   下滑更換」; until then they changed only by a swipe, with a short pause of 40svh): the section is taller than the screen by
   --industry-step (60svh) for each of its --industry-count industries (set by site-navigation.js), and the stage stays put (sticky,
   held fixed by site-navigation.js) while the page scrolls over that much. A swipe, a dot or an arrow key scrolls the page to an
   industry's stretch. */
.mega-industry-carousel { --industry-parallax: 0px; --industry-step: 60svh; position: relative; height: calc(100svh + var(--industry-step) * var(--industry-count, 5)); background: var(--mega-bg); color: #f5f2e9; }
.mega-industry-stage { position: sticky; top: 0; isolation: isolate; height: 100svh; overflow: hidden; background: var(--mega-bg); }
.mega-industry-bg { position: absolute; z-index: -3; inset: -8%; background: center / cover no-repeat; filter: blur(36px) saturate(.46) sepia(.12); transform: scale(1.13) translateY(var(--industry-parallax)); opacity: .62; transition: background-image .75s ease, transform .9s ease, opacity .65s ease; }
.mega-industry-shade { position: absolute; z-index: -2; inset: 0; background: var(--mega-bg); }
.mega-industry-bg { opacity: 0 !important; }
/* Two equal halves of the original page frame, keeping its side margins and picture proportions:
   the picture centred in the left half and a left-aligned copy block in the right half (centred in the screen's olive right half,
   further down). The title and description start at the top
   of the object in the picture, Explore All down to the object's bottom (further down, min-width: 768px).
   --picture is the side of the square image in .mega-industry-media (object-fit: contain), and every object is --object-height of
   that tall. */
/* --dots-side: from the picture's left edge to the middle of the dots' column, which stands at its left. */
.mega-industry-layout { --picture: min(32vw, 74vh, 50rem); --object-height: .9; --dots-side: 2.25rem; display: grid; height: 100svh; box-sizing: border-box; grid-template-columns: 1fr 1fr; align-content: center; align-items: center; gap: 0; padding: clamp(5rem, 10vh, 9rem) var(--mega-gutter); }
/* The picture's column: the photo (.mega-industry-media, which takes the swipes; pan-y leaves vertical scrolling to the page) and the
   dots, which stand at the picture's left (the object is --object-height of --picture tall around the box's middle, whatever the
   box's height) and so leave the row's alignment alone. The box spans the whole half (or the picture, where that is wider), so a photo sliding out
   fades through the soft edges of the half (the mask, over 80% of the room either side of the picture) instead of being cut off. */
.mega-industry-visual { position: relative; justify-self: center; width: max(100%, var(--picture)); height: min(74vh, 50rem); opacity: 0; transform: translateY(2rem); transition: opacity .75s ease, transform .9s cubic-bezier(.2,.7,.2,1); }
.mega-industry-media { --fade: calc((100% - var(--picture)) / 2 * .8); position: relative; width: 100%; height: 100%; overflow: hidden; background: var(--mega-bg); touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent); mask-image: linear-gradient(90deg, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent); }
.mega-industry-media.is-dragging { cursor: grabbing; }
/* Changing industry, as the tricorder's items change: the current photo slides out the way it was swiped (or the way the dots /
   arrow keys point) and fades, while the next slides in from the other side (--x, 55% of the picture, set by site-navigation.js). While a finger or the
   mouse drags it, the photo follows without easing; the incoming one jumps to its side first (.is-entering). */
.mega-industry-slide { position: absolute; inset: 0; margin: 0; overflow: hidden; opacity: 0; pointer-events: none; transform: translateX(var(--x, 0px)); will-change: transform, opacity; transition: opacity .45s ease, transform .6s cubic-bezier(.2, .7, .2, 1); }
.mega-industry-slide.is-active { opacity: 1; pointer-events: auto; }
.mega-industry-slide.is-entering, .mega-industry-media.is-dragging .mega-industry-slide { transition: none; }
/* Crystal product renders on pure black: each is a --picture square in the middle of the box, showing the whole object (contain), the
   black frame carrying the rest. Each image is scaled
   so its object is the same height as every other's, and moved so that object's middle is the middle of the box (--object-*, where the
   object is in its image, site-navigation.js). By scale and translate, not transform, which reduced motion switches off. */
.mega-industry-slide-image { --fit: calc(var(--object-height) / (var(--object-bottom) - var(--object-top))); position: absolute; inset: 0; display: block; width: var(--picture); height: var(--picture); margin: auto; object-fit: contain; scale: var(--fit); translate: calc(var(--picture) * var(--fit) * (.5 - (var(--object-left) + var(--object-right)) / 2)) calc(var(--picture) * var(--fit) * (.5 - (var(--object-top) + var(--object-bottom)) / 2)); transform: translateY(calc(var(--industry-parallax) * -.18)); transition: transform 1.1s ease; }
/* The renders are on pure black: lightened over the frame's ground (#151615), their black becomes exactly that ground. The blend is on the
   slide, which its transform makes a layer of its own (a blend inside it would only meet the slide's transparent box). */
.mega-industry-slide { mix-blend-mode: lighten; }
.mega-industry-content { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; opacity: 0; transform: translateY(1.3rem); transition: opacity .7s .16s ease, transform .75s .16s ease; }
/* The "01 / 05" counter is hidden on screen (the dots show the position) but stays readable to screen readers (aria-live). */
.mega-industry-count { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.mega-industry-title { margin: 0; color: #fffdf6; font: 700 var(--mega-h1)/1.2 var(--mega-font); letter-spacing: -.055em; }
.mega-industry-description { max-width: 23rem; margin: clamp(1rem, 2.5vh, 1.75rem) 0 0; color: #dfddd6; font: 400 var(--mega-body)/1.65 var(--mega-font); }
/* Frosted-glass buttons (Explore All, Get in Touch, the contact form's Send Message and the news list's read more): a square-cornered pane of
   frosted glass, evenly translucent with no hard highlight. Its layers, top first: light caught at the top left corner, a faint frost
   grain and a soft translucent white that is a little brighter towards that corner. Around them are a fine translucent edge (its top
   a touch brighter), a strong blur of whatever is behind and a soft shadow. Explore All and Get in Touch are the same size with the
   same lettering at every width; Send Message keeps 95% of the form's width. All three are 5% smaller than they were (17.4 × 4.05rem
   and the form's full width before). Hovering only sends a light sweep across the glass (::after; Send Message, an <input> with no
   pseudo-elements, has it as a background layer); the button itself does not change or move. */
.mega-industry-cta, .mega-solution-button, .contact-button, .collection-item-2 .text-block-9, .mega-news-more {
  --mega-glass-tint: linear-gradient(135deg, rgba(255, 255, 255, .2), rgba(255, 255, 255, .09) 55%, rgba(255, 255, 255, .12));
  --mega-glass: radial-gradient(130% 180% at 0% 0%, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0) 55%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 .16 0 0 0 -.04'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23f)'/%3E%3C/svg%3E"),
    var(--mega-glass-tint);
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 0; background: var(--mega-glass); color: var(--mega-text);
  box-shadow: 0 .5rem 2rem rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .28);
  -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
}
.mega-industry-cta, .mega-solution-button, .mega-news-more { position: relative; isolation: isolate; box-sizing: border-box; display: grid; width: calc(min(100vw - 2rem, 17.4rem) * .95); height: calc(4.05rem * .95); place-items: center; overflow: hidden; font: 600 .77rem/1 var(--mega-font); letter-spacing: .2em; text-decoration: none; text-transform: uppercase; }
.mega-industry-cta { margin-top: auto; }
/* Send Message: its sweep is a band in a background layer of its own, carried across once as it is hovered. */
.contact-button { display: block; width: 95%; height: calc(62px * .95); margin-inline: auto; padding-block: 0; background: linear-gradient(105deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, 0) 60%) 120% 0 / 250% 100% no-repeat, var(--mega-glass); transition: none; }
.contact-button:hover, .contact-button:focus-visible { background-color: transparent; background-position: -20% 0, 0 0, 0 0, 0 0; color: var(--mega-text); transition: background-position .95s cubic-bezier(.3, .6, .3, 1); }
@media (prefers-reduced-motion: reduce) { .contact-button:hover, .contact-button:focus-visible { background-position: 120% 0, 0 0, 0 0, 0 0; } }
/* The phones' left-aligned form inputs (further down) are not to take the button's label with them. */
.page-wrapper .contact-form .contact-button { text-align: center; }
.mega-industry-cta::after, .mega-solution-button::after, .collection-item-2 .text-block-9::after, .mega-news-more::after { position: absolute; z-index: -1; top: -50%; bottom: -50%; left: 0; width: 38%; content: ''; opacity: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent); transform: translateX(-160%) skewX(-20deg); pointer-events: none; }
.mega-industry-cta:focus-visible, .mega-solution-button:focus-visible, .mega-news-more:focus-visible { outline: 2px solid rgba(255, 255, 255, .7); outline-offset: 3px; }
.mega-industry-cta:hover::after, .mega-industry-cta:focus-visible::after, .mega-solution-button:hover::after, .mega-solution-button:focus-visible::after,
.mega-news-more:hover::after, .mega-news-more:focus-visible::after,
.collection-item-2 a:hover .text-block-9::after, .collection-item-2 a:focus-visible .text-block-9::after { animation: mega-crystal-shine .95s cubic-bezier(.3, .6, .3, 1) forwards; }
@keyframes mega-crystal-shine { 0% { opacity: 0; transform: translateX(-160%) skewX(-20deg); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateX(320%) skewX(-20deg); } }
@media (prefers-reduced-motion: reduce) { .mega-news-more:hover::after, .mega-news-more:focus-visible::after, .mega-industry-cta:hover::after, .mega-industry-cta:focus-visible::after, .mega-solution-button:hover::after, .mega-solution-button:focus-visible::after, .collection-item-2 a:hover .text-block-9::after, .collection-item-2 a:focus-visible .text-block-9::after { animation: none; } }
/* Slide indicator: one dot per industry, in a column at the picture's left, top to bottom, centred on the object's height (the user,
   2026-11-13: 「產業頁下方的圓點，改在圖片的左邊，由上往下；正在該頁的白色圓點改成長條形」; a row under the object until then); the
   current one is a bright upright bar. Each is a button that brings its industry (by scrolling to it, site-navigation.js). */
.mega-industry-dots { position: absolute; z-index: 1; top: 50%; left: calc(50% - var(--picture) / 2 - var(--dots-side)); display: flex; flex-direction: column; align-items: center; gap: .35rem; translate: -50% -50%; }
.mega-industry-dot { display: grid; width: 1.4rem; height: 1.4rem; padding: 0; border: 0; background: transparent; cursor: pointer; place-items: center; transition: height .35s ease; }
.mega-industry-dot::before { display: block; width: .5rem; height: .5rem; border-radius: .25rem; content: ''; background: rgba(245,242,233,.34); transition: background-color .35s ease, height .35s ease, box-shadow .35s ease; }
.mega-industry-dot:hover::before, .mega-industry-dot:focus-visible::before { background: rgba(255,253,246,.72); }
.mega-industry-dot.is-active { height: 2.3rem; }
.mega-industry-dot.is-active::before { height: 1.6rem; background: #fffdf6; box-shadow: 0 0 .5rem rgba(255, 253, 246, .55); }
.mega-industry-carousel.is-in-view .mega-industry-visual, .mega-industry-carousel.is-in-view .mega-industry-content { opacity: 1; transform: translateY(0); }
.mega-industry-carousel[data-active-index] .mega-industry-content { transition-delay: .08s; }
/* Beside the picture, the copy is as tall as the objects and centred on the same row, so it spans them from top to bottom and stays
   put from slide to slide. The negative margins take out the empty space above the title's characters (more above capitals than above
   Chinese), so what is seen lines up: the title's top with the object's top, Explore All's bottom with the object's bottom (with
   the dots under the picture, until 2026-11-13, it reached down to theirs).
   The right half of the screen is olive, #98982a at 30% over the ground (the user, 2026-11-11). The copy block (title, description
   and Explore All, left-aligned with each other) is centred in that olive half: its grid column runs from the middle to the right
   gutter, so the block is moved half a gutter right of the column's centre, and kept narrow enough to leave at least a gutter on
   either side. */
@media (min-width: 768px) {
  .mega-industry-shade { background: linear-gradient(90deg, var(--mega-bg) 50%, rgba(152, 152, 42, .3) 50%); }
  .mega-industry-content { position: relative; left: calc(var(--mega-gutter) / 2); justify-self: center; width: min(100% - var(--mega-gutter), 23rem); min-width: 0; min-height: calc(var(--picture) * var(--object-height)); text-align: left; }
  .mega-industry-title { margin-top: -.14em; }
  .mega-industry-title.is-latin { margin-top: -.22em; }
  /* Explore All stays frosted glass, but in the olive of the half it stands on: the glass is tinted with that olive instead of white
     and its blur does not saturate what is behind it, so the pane is the ground's own colour under the glass's light, edge and
     shadow. */
  .mega-industry-cta { --mega-glass-tint: linear-gradient(135deg, rgba(152, 152, 42, .14), rgba(152, 152, 42, .04) 55%, rgba(152, 152, 42, .08)); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); }
}

@media (max-width: 767px) {
  .mega-industry-stage { height: 100svh; }
  .mega-industry-layout { --picture: calc((100vw - 2 * var(--mega-gutter)) * .75); height: 100svh; grid-template-rows: auto minmax(0, 1fr); grid-template-columns: 1fr; align-content: start; align-items: stretch; justify-content: stretch; gap: 1.9rem; padding: 5rem var(--mega-gutter) 2rem; }
  .mega-industry-visual { width: 100%; height: auto; order: 1; }
  .mega-industry-media { height: auto; aspect-ratio: 4 / 3; }
  .mega-industry-layout { --dots-side: 1.5rem; }
  /* The title, the description and the button are centred on the screen (the user, 2026-11-13: 「產業頁，標題與描述請至中，不要貼在
     頁面的左邊」; the title and description were left-aligned until then, the button already centred). */
  .mega-industry-content { min-height: 0; order: 2; padding-top: 0; align-items: center; text-align: center; }
  .mega-industry-title { margin-top: 0; font-size: var(--mega-h1); }
  .mega-industry-description { margin-top: 1.25rem; font-size: var(--mega-body); line-height: 1.6; text-wrap: balance; }
  .mega-industry-cta { align-self: center; }
}
@media (min-width: 768px) {
  /* As wide as the fixed bar (the screen without its scrollbar), so its ends measure from the edges that are seen. */
  .mega-nav-shell { position: relative; justify-content: center; width: 100% !important; min-height: 5.1rem; margin-left: 0 !important; padding-right: 2rem; padding-left: 2rem; box-sizing: border-box; }
  .mega-nav-brand { position: absolute; left: 50%; width: 11.2875rem; transform: translateX(-50%); }
  .mega-nav-toggle { position: absolute; right: calc(var(--mega-gutter) - .5rem); display: block; }
  .mega-nav-links { position: absolute; top: 100%; left: 50%; display: grid; width: 100vw !important; min-width: 100vw; box-sizing: border-box; grid-template-columns: minmax(0, 1fr) !important; justify-content: stretch !important; justify-items: stretch !important; gap: 0; padding: .5rem 0 1rem; background: rgb(var(--mega-bg-rgb) / .96); border-top: 1px solid rgba(255,255,255,.12); text-align: center !important; transform: translate(-50%, -120%); opacity: 0; pointer-events: none; transition: transform .22s ease, opacity .22s ease; }
  .mega-nav-open .mega-nav-links { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
  .mega-nav-links > a { width: 100% !important; box-sizing: border-box; padding: 1rem .25rem; border-bottom: 1px solid rgba(255,255,255,.12); text-align: center !important; }
  .mega-nav-links > a::after { display: none; }
  .mega-nav-cta { justify-self: center; width: min(20rem, calc(100% - 4rem)) !important; margin-top: .75rem; padding-right: 2rem !important; padding-left: 2rem !important; text-align: center; border-bottom: 1px solid rgba(220,232,163,.8) !important; }
  .mega-language { justify-self: center; margin-top: .75rem; }
  .mega-language-menu { right: 50%; transform: translateX(50%); }
  .mega-nav-open .mega-nav-toggle i:first-child { transform: translateY(.18rem) rotate(45deg); }
  .mega-nav-open .mega-nav-toggle i:last-child { transform: translateY(-.18rem) rotate(-45deg); }
}
@media (prefers-reduced-motion: reduce) {
  .mega-industry-bg, .mega-industry-slide-image, .mega-industry-slide, .mega-industry-visual, .mega-industry-content { transition: opacity .2s linear; transform: none !important; }
  .mega-industry-slide, .mega-industry-slide.is-active { transition: opacity .2s linear; }
}

@media (min-width: 480px) and (max-width: 991px) {
  .service-wrapper { grid-template-rows: auto auto; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: row; }
}
@media (max-width: 767px) {
  .mega-product-search-bar { margin-bottom: 80px; }
  .mega-spectrum-process { min-height: 82rem; }
  .mega-company-ground { background: radial-gradient(ellipse 150% 15% at 99% 1%, rgba(152, 152, 42, .56) 0%, rgba(91, 91, 25, .26) 48%, transparent 80%), radial-gradient(ellipse 84% 21% at 82% 5%, rgba(152, 152, 42, .22) 0%, transparent 72%), radial-gradient(ellipse 154% 17% at 1% 20%, rgba(152, 152, 42, .54) 0%, rgba(91, 91, 25, .25) 48%, transparent 80%), radial-gradient(ellipse 88% 22% at 15% 23%, rgba(152, 152, 42, .22) 0%, transparent 72%), radial-gradient(ellipse 156% 18% at 99% 39%, rgba(152, 152, 42, .56) 0%, rgba(91, 91, 25, .26) 48%, transparent 80%), radial-gradient(ellipse 86% 24% at 83% 36%, rgba(152, 152, 42, .23) 0%, transparent 72%), radial-gradient(ellipse 154% 19% at 1% 66%, rgba(152, 152, 42, .54) 0%, rgba(91, 91, 25, .25) 48%, transparent 80%), radial-gradient(ellipse 88% 24% at 15% 70%, rgba(152, 152, 42, .22) 0%, transparent 72%), radial-gradient(ellipse 158% 17% at 99% 97%, rgba(152, 152, 42, .58) 0%, rgba(91, 91, 25, .27) 48%, transparent 80%), radial-gradient(ellipse 86% 25% at 83% 90%, rgba(152, 152, 42, .24) 0%, transparent 72%), var(--mega-bg); }
  .mega-eclipse { top: 45%; left: -22.4rem; width: 44.8rem; }
  .mega-spectrum-desktop { display: none; }
  .mega-spectrum-mobile { display: block; }
  .mega-spectrum-node { display: flex; align-items: center; width: min(22rem, 86vw); gap: .75rem; text-align: left; transform: none; }
  .mega-spectrum-node h2 { flex: 1; width: auto; margin: 0; font-size: var(--mega-h2); line-height: 1.4; }
  .mega-spectrum-process { --spectrum-marker: 7.8rem; --spectrum-height: 82rem; --spectrum-node1-y: .22; min-height: calc(var(--spectrum-height) - var(--spectrum-lift)); }
  .mega-spectrum-node-1 { left: calc(25.9% - var(--spectrum-marker) / 2); top: calc(22% - var(--spectrum-marker) / 2); }
  .mega-spectrum-node-2 { left: 74.9%; top: calc(43% - var(--spectrum-marker) / 2); flex-direction: row-reverse; transform: translateX(calc(-100% + var(--spectrum-marker) / 2)); }
  .mega-spectrum-node-3 { left: calc(25.9% - var(--spectrum-marker) / 2); top: calc(64% - var(--spectrum-marker) / 2); }
  .mega-spectrum-node-4 { left: 74.9%; top: calc(85% - var(--spectrum-marker) / 2); flex-direction: row-reverse; transform: translateX(calc(-100% + var(--spectrum-marker) / 2)); }
  .page-wrapper { text-align: left; }
  .page-wrapper .contact-form,
  .page-wrapper .contact-form input,
  .page-wrapper .contact-form textarea,
  .page-wrapper .contact-form select { text-align: left; }
  .page-wrapper .footer-top-wrap,
  .page-wrapper .bottom-content { justify-content: flex-start; }
  .page-wrapper .footer-top-wrap .phone-wrap { align-items: flex-start; }
  .page-wrapper .w-richtext,
  .page-wrapper .w-richtext * { text-align: left; }
  .footer-top-wrap .footer-nav-wrap { position: static; transform: none; }
  .page-wrapper .footer-top-wrap { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.35rem; text-align: center; }
  .footer-top-wrap > .align-right { display: none; }
  .footer-top-wrap .footer-nav-wrap { order: 1; width: 100%; text-align: center; flex-wrap: wrap; row-gap: .75rem; }
  .page-wrapper .footer-top-wrap .phone-wrap { order: 2; align-items: center; width: 100%; text-align: center; }
  .footer-top-wrap .social-icon-wrap { order: 3; justify-content: center; width: 100%; }
  .footer-top-wrap .footer-nav,
  .footer-top-wrap .phone-wrap a { text-align: center; }
  .mega-solution { min-height: calc(100svh + 8rem); padding: clamp(7.5rem, 14vw, 12rem) var(--mega-gutter); }
  .mega-solution-copy { --solution-free: 15vw; max-width: 10ch; font-size: calc(clamp(2.75rem, var(--solution-free), 5.3rem) * var(--fit, 1)); }
  .mega-solution-soft > span { white-space: normal; }
  .mega-solution-mobile-break { display: block; }
  .mega-solution-button { margin-top: 4rem; }
  .hero_main .hero-heading-wrap { top: 6rem; width: calc(100% - 2 * var(--mega-gutter)); }
  .mega-nav-shell { position: relative; justify-content: center; width: 100% !important; min-height: 4.5rem; margin-left: 0 !important; padding-right: var(--mega-gutter); padding-left: var(--mega-gutter); box-sizing: border-box; }
  .mega-nav-brand { position: absolute; left: 50%; width: 9.1875rem; transform: translateX(-50%); }
  .mega-nav-toggle { display: block; margin-right: -.5rem; }
  .mega-nav-links { position: absolute; top: 100%; left: 50%; display: grid; width: 100vw !important; min-width: 100vw; box-sizing: border-box; grid-template-columns: minmax(0, 1fr) !important; justify-content: stretch !important; justify-items: stretch !important; gap: 0; padding: .5rem 0 1rem; background: rgb(var(--mega-bg-rgb) / .96); border-top: 1px solid rgba(255,255,255,.12); text-align: center !important; transform: translate(-50%, -120%); opacity: 0; pointer-events: none; transition: transform .22s ease, opacity .22s ease; }
  .mega-nav-open .mega-nav-links { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
  .mega-nav-links > a { width: 100% !important; box-sizing: border-box; padding: 1rem .25rem; border-bottom: 1px solid rgba(255,255,255,.12); text-align: center !important; }
  .mega-nav-links > a::after { display: none; }
  .mega-nav-cta { justify-self: center; width: calc(100% - 4rem) !important; margin-top: .75rem; padding-right: 2rem !important; padding-left: 2rem !important; text-align: center; border-bottom: 1px solid rgba(220,232,163,.8) !important; }
  .mega-language { justify-self: center; margin-top: .75rem; }
  .mega-language-menu { right: 50%; transform: translateX(50%); }
  .mega-nav-open .mega-nav-toggle i:first-child { transform: translateY(.18rem) rotate(45deg); }
  .mega-nav-open .mega-nav-toggle i:last-child { transform: translateY(-.18rem) rotate(-45deg); }
}
@media (prefers-reduced-motion: reduce) {
  .mega-solution-char { animation: none !important; transition: none; }
}

/* Navigation: both controls reveal a compact panel beneath their own icon. The menu and language items are subtitle size
   (--mega-subtitle: 26px, 22px on phones), and each panel is as wide as its longest item.
   The menu panel mirrors the language panel: its right edge sits on the page's side margin, in line with the menu bars' outer edge,
   and its top is level with the language panel's (the bar's centre line, plus half the 1.5rem globe, plus .65rem).
   Menu items set like the subtitles (light 300, normal tracking; the user, 2026-11-12: 選單字體改成子標題的大小), keeping their
   1.2 line height and padding so the spacing between items stays. The frame-to-text margin is 1.5 times the old one on all four
   sides (上下左右寬度增加1.5倍): it was .4rem panel + .65rem / .75rem item padding, so the panel's padding is now
   1.5 × (.4 + .65) − .65 = .925rem above and below, and 1.5 × (.4 + .75) − .75 = .975rem left and right.
   The whole frame is then 1.2 times as wide as that (the user, 2026-11-12: 整個選單框變成 1.2 倍寬): site-navigation.js measures the
   panel when it opens and sets --panel-extra to a tenth of its width, added to the left and the right margin.
   An item's highlight (hover, current page) reaches to 8px from the frame on the left and the right (the user, 2026-11-12:
   選單的底色左右寬度與邊寬距離8px): the panel keeps 8px at its sides, and the rest of that margin (.975rem − 8px + --panel-extra,
   which the items inherit) is the items' own padding, so the text stays where it was and the frame keeps its width. */
.mega-nav-links[hidden] { display: none !important; }
.mega-nav-links {
  position: absolute;
  top: calc(50% + .75rem + .65rem);
  right: var(--mega-gutter);
  left: auto;
  z-index: 3;
  display: block;
  width: max-content !important;
  min-width: 0;
  box-sizing: border-box;
  padding: .925rem 8px;
  border: 1px solid rgba(220,232,163,.7);
  background: rgb(var(--mega-bg-rgb) / .97);
  box-shadow: 0 .75rem 2rem rgba(0,0,0,.3);
  opacity: 1;
  pointer-events: auto;
  text-align: left !important;
  transform: none;
}
.mega-nav-open .mega-nav-links { transform: none; opacity: 1; pointer-events: auto; }
.mega-nav-links > a,
.mega-nav-links > a.mega-nav-cta {
  display: block;
  width: 100% !important;
  margin: 0;
  padding: .65rem calc(.975rem + .75rem - 8px + var(--panel-extra, 0px)) !important;
  box-sizing: border-box;
  border: 0 !important;
  background: transparent;
  color: rgba(255,255,255,.86) !important;
  font: 300 var(--mega-subtitle)/1.2 var(--mega-font);
  letter-spacing: normal;
  text-align: left !important;
}
.mega-nav-links > a:hover,
.mega-nav-links > a[aria-current="page"] { background: rgba(220,232,163,.16); color: var(--mega-text) !important; }
.mega-nav-links > a span { color: #dce8a3; }


/* Homepage company introduction: remove only the prism image. */
.page-wrapper:has(.hero_main) .section:has(.main-content) .about-img-wrap { visibility: hidden; }
.mega-spectrum-char { display: inline; color: #4a4a4a; transition: color .12s linear; }
/* 非接觸 section visual (site-navigation.js initExpertiseBrain): a screen-wide stage with the glass cube centred, 40% of the screen
   wide at most (three quarters on phones). The cube's layers fill its box: back (the cube without its brain), the see-through 3D
   brain canvas (fading in once it is built, .is-3d) and front (the front edges). Only where the 3D brain cannot be drawn does
   site-navigation.js add the photo's own brain on top instead, also see-through.
   Black in the layers is transparent, so the glass shows the section's glow through it. The cube sits in a sticky pin that holds it in
   the middle of the screen while the stage (taller than the pin, sized by site-navigation.js) scrolls past. The callout rings and
   lines are an SVG over the pin; each label (H1 size) sits above its line's level run, at the outer end. Two callout sets: the
   features, then the figures, revealed and hidden by the scroll (site-navigation.js). */
.mega-brain { position: relative; display: block; margin: clamp(0rem, 2vw, 2rem) 0 clamp(3.5rem, 7vw, 6rem); }
.mega-brain-pin { position: sticky; display: block; overflow-x: clip; }
/* The 0/1 field behind the features: screen-sized, under the cube and the callouts (site-navigation.js sizes, places and draws it),
   the whole field at 40% of the digits' own strengths (80% until the user halved it, 2026-11-11: 連一般 0/1 也要一起減半). */
.mega-brain-binary { position: absolute; left: 0; display: block; opacity: calc(.4 * var(--binary-keep, 1)); pointer-events: none; }
/* The software graphics behind the figures (site-navigation.js initSoftwareWindows): screen-sized like the 0/1 field and under the
   cube and the callouts: a concentration chart as large as the screen and a log window, which site-navigation.js places clear of the
   figures' labels. Both open and fill with the scroll. */
.mega-brain-apps { position: absolute; left: 0; display: block; pointer-events: none; color: rgba(255, 255, 255, .62); font: 400 clamp(10px, .75vw, 12px)/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .02em; text-align: left; text-transform: none; }
/* The chart: drawn at the screen's size with its lines, dots and type magnified (their sizes set by site-navigation.js, which fades
   it in to 30%). svg. beats Webflow's svg:not(:root) { overflow: hidden }. */
svg.mega-app-stream { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; opacity: 0; }
.mega-stream-grid line { stroke: rgba(255, 255, 255, .08); }
.mega-stream-line { fill: none; stroke: rgba(255, 255, 255, .8); stroke-linejoin: round; }
.mega-stream-line.is-olive { stroke: #98982a; }
.mega-stream-dot { fill: #fff; }
.mega-stream-cursor { stroke: rgba(255, 255, 255, .35); }
.mega-app-stream text { fill: rgba(255, 255, 255, .4); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .04em; }
.mega-app-stream .mega-stream-reading { fill: rgba(255, 255, 255, .85); font-size: 9px; }
/* The log window, in the chart's bottom left corner: a fine frame with square corners like the site's buttons and small, dim
   monospace type, with no background of its own (the chart is kept out from under it, site-navigation.js). */
.mega-app { position: absolute; box-sizing: border-box; overflow: hidden; border: 1px solid rgba(255, 255, 255, .1); color: rgba(255, 255, 255, .4); opacity: 0; }
.mega-app[hidden] { display: none; }
.mega-app-bar { display: flex; align-items: center; gap: 10px; height: 26px; padding: 0 10px; border-bottom: 1px solid rgba(255, 255, 255, .07); background: rgba(255, 255, 255, .03); font-size: .9em; letter-spacing: .16em; white-space: nowrap; }
.mega-app-title { color: rgba(255, 255, 255, .55); }
.mega-app-controls { display: flex; gap: 5px; margin-left: auto; }
.mega-app-controls i { display: block; width: 7px; height: 7px; border: 1px solid rgba(255, 255, 255, .2); }
.mega-app-body { padding: 10px 12px 12px; }
/* Typed with the scroll; the cursor blinks on the line being typed (while the windows can be seen, .is-live). */
.mega-app-log { margin: 0; padding: 0; list-style: none; white-space: pre; }
.mega-app-log li { min-height: 1.5em; }
.mega-app-log .is-typing::after { content: ''; display: inline-block; width: .6em; height: 1.1em; margin-left: 1px; vertical-align: -.2em; background: rgba(255, 255, 255, .45); }
.mega-brain-apps.is-live .mega-app-log .is-typing::after { animation: mega-app-blink 1s steps(1) infinite; }
@keyframes mega-app-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .mega-brain-apps.is-live .mega-app-log .is-typing::after { animation: none; }
}
@media (max-width: 767px) {
  .mega-brain-apps { font-size: 9px; }
  .mega-app-bar { gap: 8px; height: 22px; padding: 0 8px; }
  .mega-app-controls i { width: 6px; height: 6px; }
  .mega-app-body { padding: 8px 9px 9px; }
}
.mega-brain-cube { --brain-drop: 10px; position: relative; display: block; width: min(40vw, 65.6svh, 38.4rem); aspect-ratio: 1; margin: 0 auto; }
.mega-brain-cube > img, .mega-brain-cube > canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; max-width: none; }
.mega-brain-cube > .mega-brain-photo { inset: auto; left: 19.57%; top: 14.13%; width: 60.87%; height: 60.87%; }
/* The brain (3D or photo) sits a little lower in the cube than in the photo; the callout rings follow (site-navigation.js). */
.mega-brain-cube > .mega-brain-canvas, .mega-brain-cube > .mega-brain-photo { translate: 0 var(--brain-drop); }
.mega-brain-canvas { opacity: 0; transition: opacity .9s ease; }
.mega-brain.is-3d .mega-brain-canvas { opacity: 1; }
/* svg. so overflow: visible beats Webflow's svg:not(:root) { overflow: hidden } (callouts may run past the pin, e.g. on phones). */
svg.mega-brain-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
/* End of the pin: the screen goes black, grainy, with an RGB spectrum flowing in its top part and the first description under it,
   which then zooms away into the black before the tricorder game. site-navigation.js sizes the overlay to the screen plus a 0.4-screen
   tail (its gradient's last 2/7) that fades out below, so it leaves without an edge when the pin lets go, and places the spectrum, the
   copy and the game. */
.mega-brain-dark { position: absolute; z-index: 2; left: 0; right: 0; display: block; opacity: 0; pointer-events: none; background: linear-gradient(var(--mega-bg) calc(100% / 1.4), rgb(var(--mega-bg-rgb) / 0)); }
/* It clips what is in it, so nothing in it can make the page longer (the light that dived into the description, 37.5 times the screen,
   once did: the user, 2026-11-12: 「為什麼到頁尾，後面還有一大堆黑色空白的頁面」). Clipping here, inside the pin, not round it, keeps the
   pin's sticky smooth on iPhones (an ancestor that clips makes WebKit move it on the main thread). */
.mega-brain-dark { overflow: hidden; overflow: clip; }
/* The light's layer (the spectrum), the screen's size: going on to the game the view dives into it, until only black is left
   (site-navigation.js sets its size, transform-origin, transform and opacity). The copy is not in it: it stays and dissolves. */
.mega-brain-scene { position: absolute; left: 0; top: 0; display: block; will-change: transform, opacity; }
/* The spectrum and the grain (site-navigation.js createSpectrum): an opaque canvas the size of the screen, under the copy, drawn in
   the overlay's own black. (It replaced the high-SNR diagram and the light ring, 2026-11-11.) */
.mega-brain-spectrum { position: absolute; left: 0; top: 0; display: block; }
/* The description, under the spectrum: one paragraph (until 2026-11-11 two groups of lines set as given), its lines balanced and
   centred, each character revealed by the scroll. site-navigation.js gives it its width. */
/* The description's layer (as big as the screen, site-navigation.js) and its two windows, the same as the game's intro windows
   (.mega-tricorder-corner, below): the first at the top left, the second at the bottom right, right-aligned. */
.mega-brain-copy { position: absolute; left: 0; top: 0; display: block; pointer-events: none; }
/* Each is exactly the game's window in its corner (site-navigation.js gives it that box), the game's frame drawn round it, so it has
   none of its own (a clear 1px edge keeps the text where the game's is); its text left-aligned (the user, 2026-11-13: 「全部靠左對齊」). */
.mega-brain-window { position: absolute; display: block; box-sizing: border-box; padding: 18px 22px; border: 1px solid transparent; color: var(--mega-text); }
.mega-brain-window .mega-brain-words { font-size: calc(var(--mega-h2) * .62 * var(--fit, 1)); line-height: 1.6; text-align: left; }
/* The typewriter's caret (site-navigation.js megaType): a thin bar after the last character typed, blinking. */
.mega-type-caret { position: absolute; display: block; width: 2px; opacity: 0; background: var(--mega-text); pointer-events: none; }
.mega-type-caret.is-on { animation: mega-type-blink 1.05s steps(1, end) infinite; }
@keyframes mega-type-blink { 0% { opacity: 1; } 55% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .mega-type-caret.is-on { animation: none; opacity: 1; } }
.mega-brain-words { display: block; color: var(--mega-text); font: 500 calc(var(--mega-h2) * var(--fit, 1))/1.5 var(--mega-font); letter-spacing: .04em; text-align: left; text-wrap: balance; }
.mega-brain-words + .mega-brain-words { margin-top: .6em; }
.mega-brain-line { display: block; }
.mega-brain-whole { white-space: nowrap; }
.mega-brain-word { opacity: 0; }
/* On phones the description and the game's intro are set exactly as H2 is there (26px, line-height 1.4, no extra tracking), like the
   page's other H2 copy. */
@media (max-width: 767px) {
  .mega-brain-dark .mega-brain-words, .mega-brain-dark .mega-tricorder-copy { line-height: 1.4; letter-spacing: 0; }
}
/* Every language is laid out as 繁體中文 (site-navigation.js megaReference / megaFitText): the ring and the texts' boxes are measured
   from a hidden copy of the texts in 繁體中文 (.mega-text-reference), and a translation is fitted into zh-TW's box. So that it can
   wrap there, outside Chinese the description's and the intro's lines may break, inside the intro's phrases too (between words;
   Korean only at spaces, Japanese between its phrases, below). Where wrapping is not enough --fit sets the texts smaller (1 in zh-TW). */
.mega-brain-words:not(:lang(zh)), .mega-tricorder-line:not(:lang(zh)) { white-space: normal; }
.mega-tricorder-phrase:not(:lang(zh)) { display: inline; }
.mega-brain-words:lang(ko), .mega-tricorder-copy:lang(ko) { word-break: keep-all; }
/* A line that wraps is balanced (no word left alone on its last line), and Japanese breaks between phrases, not inside a word
   (Chrome's auto-phrase; elsewhere it breaks as usual). */
.mega-brain-line:not(:lang(zh)), .mega-tricorder-line:not(:lang(zh)) { text-wrap: balance; }
.mega-brain-words:lang(ja), .mega-tricorder-copy:lang(ja) { word-break: auto-phrase; }
.mega-text-reference { position: absolute; inset: 0; pointer-events: none; }
.mega-text-reference, .mega-text-reference * { visibility: hidden !important; }
/* Tricorder game (site-navigation.js initTricorder; from 2026/tricorder game): the item floats in the very middle of the screen, in
   the scanner (the circle that takes the taps), and the panel is beside it on the left, or under it on phones (placeTricorder). Both
   are inert and let the page take the pointer until the game has come in (.is-playing). */
.mega-tricorder-panel { position: absolute; z-index: 5; display: grid; width: max-content; color: var(--mega-text); opacity: 0; pointer-events: none; }
/* The intro, 檢測中… and the results share one grid cell, so the panel is as big as the biggest and nothing moves when they swap; the
   one showing (.is-shown) fades in over the last. */
.mega-tricorder-panel > * { grid-area: 1 / 1; align-self: center; margin: 0; opacity: 0; visibility: hidden; transition: opacity .4s ease, visibility 0s linear .4s; }
.mega-tricorder-panel > .is-shown { opacity: 1; visibility: visible; transition: opacity .6s ease .15s, visibility 0s; }
/* With a mouse, the hint shows only while the pointer is over the item, beside the pointer (or, with the keyboard's focus on the item,
   under it): site-navigation.js sets .is-item-hover, and .is-hint-at-pointer with --hint-x / --hint-y. Touch screens keep it showing
   under the item. */
@media (hover: hover) and (pointer: fine) {
  .mega-brain-dark > .mega-tricorder-panel > .mega-tricorder-intro { transition: opacity .25s ease, visibility 0s; }
  .mega-brain-dark:not(.is-item-hover) > .mega-tricorder-panel > .mega-tricorder-intro { opacity: 0; }
  .mega-brain-dark.is-hint-at-pointer > .mega-tricorder-panel { left: var(--hint-x) !important; top: var(--hint-y) !important; }
}
.mega-brain.is-playing .mega-tricorder-scanner { pointer-events: auto; }
.mega-brain-dark.is-stacked .mega-tricorder-panel { text-align: center; }
/* The intro: two groups of lines (each character revealed by the scroll) and the hint below. A line breaks only between its phrases. */
.mega-tricorder-copy { margin: 0; font: 500 calc(var(--mega-h2) * .62 * var(--fit, 1))/1.6 var(--mega-font); letter-spacing: .04em; }
/* The intro's two sentences in the screen's corners (site-navigation.js placeTricorder places and fits them; they fade in with the game),
   each in a small window (the user, 2026-11-12: 「介面左上有一個小視窗…在視窗內，右下角也有一個小視窗…在視窗內」, after a HUD interface
   they sent): a thin edge, its top left and bottom right corners marked brighter; the first at the top left, the second at the bottom
   right, right-aligned. Over the scan frame's olive (z-index 5), so they stay white where it passes; only their key words take the
   olive there (.is-key). */
.mega-tricorder-corner { position: absolute; z-index: 5; display: block; box-sizing: border-box; width: max-content; padding: 18px 22px; border: 1px solid rgba(255, 255, 255, .24); color: var(--mega-text); opacity: 0; pointer-events: none; }
.mega-tricorder-corner::before, .mega-tricorder-corner::after { content: ""; position: absolute; width: 12px; height: 12px; border: 0 solid var(--mega-text); }
.mega-tricorder-corner::before { left: -1px; top: -1px; border-width: 2px 0 0 2px; }
.mega-tricorder-corner::after { right: -1px; bottom: -1px; border-width: 0 2px 2px 0; }
/* A key word's character: white, and the site's olive where the scan frame is over it. It is drawn twice over itself (its own text
   kept for the layout, unseen): white, with the frame's rectangle cut out, and olive, cut down to that rectangle (site-navigation.js
   sets --kl, --kt, --kr, --kb, the rectangle in the character's box; none at first). Plain text both, so it is drawn as crisply as the
   rest (a background cut to the letters came out thinner). */
.mega-tricorder-char.is-key { position: relative; color: transparent; }
.mega-tricorder-char.is-key::before, .mega-tricorder-char.is-key::after { content: attr(data-char); position: absolute; left: 0; top: 0; line-height: normal; white-space: pre; }
.mega-tricorder-char.is-key::before { color: var(--mega-text); clip-path: polygon(-50% -50%, 150% -50%, 150% 150%, -50% 150%, -50% -50%, var(--kl, 0px) var(--kt, 0px), var(--kl, 0px) var(--kb, 0px), var(--kr, 0px) var(--kb, 0px), var(--kr, 0px) var(--kt, 0px), var(--kl, 0px) var(--kt, 0px)); }
.mega-tricorder-char.is-key::after { color: #98982a; clip-path: polygon(var(--kl, 0px) var(--kt, 0px), var(--kr, 0px) var(--kt, 0px), var(--kr, 0px) var(--kb, 0px), var(--kl, 0px) var(--kb, 0px)); }
.mega-tricorder-words { display: block; }
.mega-tricorder-words + .mega-tricorder-words { margin-top: .6em; }
/* A line breaks only between its phrases, where it has to (the panel beside the item is narrower than a line on most screens since
   2026-11-12; better that than the intro set smaller). */
.mega-tricorder-line { display: block; }
.mega-tricorder-phrase { display: inline-block; }
/* A 繁體 / 简体 phrase never breaks inside (an inline block would, where it is wider than the room left for it). */
.mega-tricorder-phrase:lang(zh) { white-space: nowrap; }
.mega-tricorder-char { opacity: 0; }
/* The hint under the intro and each result, 點一下檢測物品, with a light sweeping across it, in a box (a thin edge on a faint fill, as
   the button of the reference interface the HUD follows; a line runs from its right side to the HUD's lens). (Until 2026-11-12 it sat
   between previous / next arrows.) padding-left balances the trailing letter-spacing. */
.mega-tricorder-hint { display: flex; align-items: center; justify-content: center; gap: 6px; box-sizing: border-box; width: max-content; min-height: 46px; margin: 2rem 0 0; padding: 0 1.6em; border: 1px solid rgba(255, 255, 255, .26); background: rgba(255, 255, 255, .03); }
.mega-tricorder-intro > .mega-tricorder-hint { margin-top: 0; }
.mega-tricorder-hint-text { padding-left: .24em; font: 500 14px/1.4 var(--mega-font); letter-spacing: .24em; white-space: nowrap; color: transparent; background: linear-gradient(100deg, rgba(255, 255, 255, .65) 40%, var(--mega-text) 50%, rgba(255, 255, 255, .65) 60%) 0 0 / 250% 100%; -webkit-background-clip: text; background-clip: text; animation: mega-tricorder-sweep 3.2s linear infinite; }
/* The scanner, the circle round the item (where the light ring used to be): a tap or a click on it (or Enter / Space, or the arrow
   keys) changes the item. touch-action leaves scrolling to the page but lets a tap through at once. No z-index, so the items' screen
   blend reaches the black below. */
.mega-tricorder-scanner { position: absolute; border-radius: 50%; cursor: pointer; touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.mega-tricorder-scanner:focus { outline: none; }
.mega-tricorder-scanner:focus-visible .mega-tricorder-items { border-radius: 50%; outline: 1px dashed rgba(255, 255, 255, .45); outline-offset: 10px; }
/* The items, floating gently in the middle of the scanner (0.595 of it). Each photo is cropped so its object fits the circle
   inside this box; the photos are on black, which the screen blend drops (on the group too, which its fade makes its own layer). The
   current item shows; the others wait at the sides (--x) and slide through as the item changes. */
.mega-tricorder-items { position: absolute; left: 20.25%; top: 20.25%; width: 59.5%; height: 59.5%; mix-blend-mode: screen; opacity: 0; animation: mega-tricorder-float 6s ease-in-out infinite; }
.mega-tricorder-item { position: absolute; inset: 0; display: block; width: 100%; height: 100%; max-width: none; mix-blend-mode: screen; opacity: 0; transform: translateX(var(--x, 0px)); transition: opacity .45s ease, transform .6s cubic-bezier(.2, .7, .2, 1); pointer-events: none; -webkit-user-drag: none; }
.mega-tricorder-item.is-current { opacity: 1; }
.mega-tricorder-item.is-entering { transition: none; }
/* Every 3 s a small light taps the middle of the item and a ripple spreads from it: a hint that the item can be tapped (it replaced a
   light gliding across the item when the item was swiped, 2026-11-12). It comes in with the hint 點一下檢測物品 (site-navigation.js sets
   its opacity) and is gone while the item is detected; whenever it is back it starts over, after a 1 s pause. Both are drawn on the
   items' box, so they float with the item: the light (::after, a white core in a soft glow) appears, presses in and springs back, then
   fades; the ripple (::before, a thin bright ring) grows from it to three quarters of the box, fading as it goes. */
.mega-tricorder-tap { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.mega-tricorder-tap > span { position: absolute; inset: 0; }
.mega-tricorder-tap > span::before, .mega-tricorder-tap > span::after { content: ''; position: absolute; left: 50%; top: 50%; border-radius: 50%; translate: -50% -50%; }
.mega-tricorder-tap > span::before { width: 74%; aspect-ratio: 1; box-sizing: border-box; border: 1.5px solid rgba(255, 255, 255, .8); box-shadow: 0 0 14px rgba(255, 255, 255, .35), inset 0 0 14px rgba(255, 255, 255, .2); animation: mega-tricorder-tap-ring 3s 1s infinite backwards; }
.mega-tricorder-tap > span::after { width: clamp(24px, 3.8vmin, 34px); aspect-ratio: 1; background: radial-gradient(circle closest-side, #fff 26%, rgba(255, 255, 255, .8) 36%, rgba(255, 255, 255, .35) 60%, rgba(255, 255, 255, 0)); animation: mega-tricorder-tap-light 3s 1s infinite backwards; }
.mega-brain.is-scanning .mega-tricorder-tap { display: none; }
/* The game's grain (site-navigation.js paintGrain): the description page's noise, painted once at a CSS px a cell and shown pixelated,
   under everything of the game; it comes in with the game. */
.mega-tricorder-grain { position: absolute; left: 0; top: 0; display: block; opacity: 0; image-rendering: pixelated; pointer-events: none; }
/* The game's HUD (site-navigation.js createTricorderHud, after the reference interface the user gave on 2026-11-12): over the game,
   the three small labels by the item (12px, ????? beside the ? ball) and, at the foot, the time (bold) and the date. All of it fades in
   with the game, and none of it takes the pointer. (Its thin lines, small boxes and faint figures were removed the same day: 「背景那些
   細細的線和方塊都刪除，只要留下大的掃描框即可」.) */
.mega-hud { position: absolute; left: 0; top: 0; z-index: 2; display: block; opacity: 0; pointer-events: none; color: rgba(255, 255, 255, .62); font: 400 12px/1.3 var(--mega-font); letter-spacing: .05em; }
.mega-hud > * { position: absolute; white-space: nowrap; }
/* The labels round the item (site-navigation.js placeLabels sets each one's place, alignment and anchor): ????? in the HUD's layer,
   cut away where the scan frame is, and the component in .mega-hud-reveal, over the frame's olive, cut down to the frame; on phones the
   component's share goes under its name. */
.mega-hud-labels, .mega-hud-reveal { position: absolute; left: 0; top: 0; display: block; pointer-events: none; }
.mega-hud-reveal { z-index: 4; opacity: 0; color: var(--mega-text); font: 500 12px/1.3 var(--mega-font); letter-spacing: .05em; }
/* Both at 18px, 15px on phones (12px until 2026-11-13, the user: 「???和成分的字太小了」), the same size so a label keeps its size as the
   frame crosses it. */
.mega-hud-labels, .mega-hud-reveal { font-size: 18px; }
.mega-brain-dark.is-stacked :is(.mega-hud-labels, .mega-hud-reveal) { font-size: 15px; }
.mega-hud-labels > .mega-hud-label, .mega-hud-reveal > .mega-hud-label { position: absolute; white-space: nowrap; letter-spacing: .12em; }
.mega-hud-reveal b { margin-left: .5em; font-weight: 700; font-variant-numeric: tabular-nums; }
.mega-brain-dark.is-stacked .mega-hud-reveal b { display: block; margin-left: 0; }
/* Over the game the site's cursor is a thin ring, without its glow and light, so the label under it (at the scan frame's middle) can be
   read (site-navigation.js createTricorderHud toggles html.mega-cursor-scope). */
html.mega-cursor-scope .mega-cursor-core { width: 1.1rem; height: 1.1rem; margin: -.55rem 0 0 -.55rem; box-sizing: border-box; border: 1px solid rgba(255, 255, 255, .85); background: none; filter: none; }
html.mega-cursor-scope :is(.mega-cursor-glow, .mega-cursor-light) { opacity: 0; }
/* The time (bold) and the date in the bottom left corner, left-aligned (site-navigation.js places its foot), over the scan frame's olive
   so it stays white. */
.mega-hud-time { position: absolute; z-index: 5; display: grid; justify-items: start; gap: 4px; translate: 0 -100%; opacity: 0; pointer-events: none; white-space: nowrap; color: rgba(255, 255, 255, .9); font: 400 11px/1.3 var(--mega-font); letter-spacing: .05em; font-variant-numeric: tabular-nums; }
.mega-hud-time b { font-weight: 700; }
/* The lens, the big scan frame: a frame (a thin light edge, the pointer's place written over its top left corner) and, under it, a
   layer that multiplies everything in the game's layer by the site's olive, #98982a (blue until 2026-11-12: 「掃描框的藍色改成#98982a」),
   so whatever the lens passes over shows olive. While an item is detected (.is-scanning) a line sweeps down the frame.
   site-navigation.js moves and sizes both. */
.mega-hud-lens, .mega-hud-frame { position: absolute; left: 0; top: 0; z-index: 3; display: block; opacity: 0; pointer-events: none; }
.mega-hud-lens { background: #98982a; mix-blend-mode: multiply; }
.mega-hud-frame { box-sizing: border-box; border: 1px solid rgba(255, 255, 255, .72); }
/* On a touch screen the frame can be held and dragged (site-navigation.js createTricorderHud) while the game is played: it takes the
   touch, and the page does not scroll under the finger. */
@media not all and (hover: hover) and (pointer: fine) {
  .mega-brain.is-playing .mega-hud-frame { pointer-events: auto; touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
}
.mega-hud-coords { position: absolute; left: -1px; bottom: calc(100% + 7px); color: rgba(255, 255, 255, .62); font: 400 10px/1 var(--mega-font); letter-spacing: .06em; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Stacked (phones), the item's own labels sit above the lens, so its place is written under its bottom left corner instead. */
.mega-brain-dark.is-stacked .mega-hud-coords { top: calc(100% + 7px); bottom: auto; }
.mega-hud-scanline { position: absolute; left: 0; right: 0; top: 0; height: 1px; opacity: 0; background: #ececb4; box-shadow: 0 0 10px 1px rgba(152, 152, 42, .9); }
.mega-hud-frame.is-scanning .mega-hud-scanline { animation: mega-hud-scan var(--scan, 1.5s) cubic-bezier(.45, 0, .55, 1); }
@keyframes mega-hud-scan { 0% { top: 0; opacity: 0; } 10%, 88% { opacity: 1; } 100% { top: 100%; opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .mega-hud-frame.is-scanning .mega-hud-scanline { animation: none; } }
/* Read out by screen readers only: 檢測中… and then the result. */
.mega-tricorder-status { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@keyframes mega-tricorder-float { 0%, 100% { translate: 0 -1.2%; } 50% { translate: 0 1.2%; } }
@keyframes mega-tricorder-sweep { from { background-position: 100% 0; } to { background-position: 0 0; } }
/* The tap's 3 s: the light appears (0.3–0.6 s), presses in and springs back (0.6–1 s) and fades (1.65–2.05 s); the ripple leaves it as it
   springs back (from 0.9 s) and has spread and gone by 2.15 s. */
@keyframes mega-tricorder-tap-light { 0%, 10% { opacity: 0; scale: .3; } 20% { opacity: 1; scale: 1; } 26% { scale: .7; } 33% { scale: 1; } 55% { opacity: 1; scale: 1; } 68%, 100% { opacity: 0; scale: .8; } }
@keyframes mega-tricorder-tap-ring { 0%, 29% { opacity: 0; scale: .1; } 33% { opacity: .85; } 72%, 100% { opacity: 0; scale: 1; } }
/* Narrower landscape screens keep the panel beside the item by narrowing it: the intro's lines wrap between phrases. */
@media (max-width: 1179px) {
  .mega-tricorder-panel { max-width: calc(var(--mega-h2) * 11.6); }
  .mega-tricorder-line { white-space: normal; }
}
@media (max-width: 767px) {
  .mega-tricorder-panel { max-width: calc(100vw - 32px); }
  .mega-tricorder-copy { font-size: calc(var(--mega-h2) * .68 * var(--fit, 1)); }
  .mega-tricorder-corner, .mega-brain-window { padding: 14px 16px; }
  .mega-brain-window .mega-brain-words { font-size: calc(var(--mega-h2) * .68 * var(--fit, 1)); line-height: 1.4; }
}
@media (prefers-reduced-motion: reduce) {
  .mega-tricorder-items { animation: none; }
  .mega-tricorder-item { transform: none; transition: opacity .2s ease; }
  .mega-tricorder-tap { display: none; }
  .mega-tricorder-hint-text { animation: none; color: rgba(255, 255, 255, .85); background: none; }
}
/* Callout parts start hidden; site-navigation.js reveals them with the scroll (ring opacity / scale, line dash offset, label opacity /
   rise). */
.mega-brain-lines path { fill: none; stroke: #fff; stroke-width: 1.5; stroke-dasharray: 1; stroke-dashoffset: 1; }
.mega-brain-ring { fill: rgba(0, 0, 0, .25); stroke: #fff; stroke-width: 1.5; }
.mega-brain-dot { fill: #fff; filter: drop-shadow(0 0 4px rgba(255, 253, 230, .9)); }
.mega-brain-ring, .mega-brain-dot { opacity: 0; transform: scale(.3); transform-box: fill-box; transform-origin: center; }
.mega-brain-label { position: absolute; display: block; padding-bottom: calc(.45rem + 10px); color: var(--mega-text); font: 500 calc(var(--mega-h1) * var(--fit, 1))/1.2 var(--mega-font); letter-spacing: .04em; white-space: nowrap; opacity: 0; transform: translateY(-100%); translate: 0 .5rem; }
.mega-brain-label[data-side="right"] { text-align: right; }
/* A translation too long for its room (site-navigation.js layoutCallouts) wraps where a line may break: at spaces and hyphens, never
   inside a CJK word; --fit sets it smaller where that is not enough. */
.mega-brain-label.is-wrapping { white-space: normal; word-break: keep-all; overflow-wrap: normal; text-wrap: balance; }
/* Japanese may break between phrases (リアルタイム｜監視) where the browser can find them (Chrome's auto-phrase); elsewhere keep-all
   holds and the label is set smaller instead. */
.mega-brain-label.is-wrapping:lang(ja) { word-break: auto-phrase; }
/* Figures: the caption over the figure, its number larger than the unit. Both lines shrink to their text (so the callout layout can
   measure it), aligned to the label's outer end. */
.mega-brain-figure { display: flex; flex-direction: column; align-items: flex-start; }
.mega-brain-figure[data-side="right"] { align-items: flex-end; }
.mega-brain-caption { font-size: calc(var(--mega-subtitle) * var(--fit, 1)); line-height: 1.4; letter-spacing: .06em; }
.mega-brain-value { line-height: 1.05; white-space: nowrap; }
.mega-brain-value b { margin-right: .08em; font-size: 1.6em; font-weight: 700; letter-spacing: -.02em; }
@media (max-width: 767px) {
  /* Room above and below the cube for the labels (they sit there on phones). */
  .mega-brain-pin { padding: 4.75rem 0 5.75rem; }
  .mega-brain-cube { width: min(75.2vw, 57.6svh); }
  /* The labels (and the figures' captions) are 20% smaller than the H1 / subtitle sizes; the figures' numbers follow (1.6em). */
  .mega-brain-label { padding-bottom: calc(.3rem + 10px); font-size: calc(var(--mega-h1) * .8 * var(--fit, 1)); letter-spacing: .02em; }
  .mega-brain-caption { font-size: calc(var(--mega-subtitle) * .8 * var(--fit, 1)); }
}
/* The phone layout on a wider screen (a tablet held upright gets it at 767px since 2026-11-13, site-loader.js): the cube no bigger than
   26rem and the labels at their full H1 / subtitle sizes, so the cube and the text keep about a phone's proportions (the user,
   2026-11-13: 「平板介面核心技術圖片和文字的比例非常奇怪」: the cube was 75% of the width, 577px, beside phone-sized labels). */
@media (min-width: 560px) and (max-width: 767px) {
  .mega-brain-cube { width: min(75.2vw, 57.6svh, 26rem); }
  .mega-brain-label { font-size: calc(var(--mega-h1) * var(--fit, 1)); }
  .mega-brain-caption { font-size: calc(var(--mega-subtitle) * var(--fit, 1)); }
}


@media (max-width: 767px) {
  .page-wrapper:has(.hero_main) .section:has(.main-content) .about-img-wrap { display: none; }
}

/* Homepage introduction and expertise sections: remove plus ornaments. */
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .code-embed-5,
.page-wrapper:has(.hero_main) .section:has(.about-img-wrap) .about-fact > div:not(.fact-wrap) { display: none !important; }
@media (min-width: 768px) {
  .page-wrapper:has(.hero_main) .section:has(.service-wrapper) .left-content {
    display: block !important;
    visibility: hidden;
  }
}
.page-wrapper:has(.hero_main) .section:has(.service-wrapper) .service-wrapper,
.page-wrapper:has(.hero_main) .section:has(.service-wrapper) .blank-space { display: none; }

/* About hero: the company photo fills the left half of the first screen, the left-aligned MEGA CRYSTAL title the right half.
   With JS and motion allowed, the photo stays pinned while scrolling dissolves the title into the statement (site-navigation.js). */
.mega-about-hero-stage { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); min-height: 100svh; }
.mega-about-hero-media { position: relative; overflow: hidden; }
.mega-about-hero-media .about-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; }
.mega-about-hero-content { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 3rem; padding: 6rem clamp(1.5rem, 5vw, 6rem); }
.mega-about-hero .about-hero_heading .display-01 { font-size: min(9vw, 11.25rem); line-height: .93; letter-spacing: -.035em; text-align: left; white-space: nowrap; overflow-wrap: normal; }
.mega-about-hero-statement { margin: 0; font-size: min(3.4vw, 4.25rem); font-weight: 500; line-height: 1.45; letter-spacing: .02em; }
.mega-about-hero-line { display: block; white-space: normal; text-wrap: pretty; }
.mega-about-hero-line .mega-about-word { display: inline-block; white-space: nowrap; }
.mega-about-hero-line .mega-about-char { display: inline-block; }
.mega-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (prefers-reduced-motion: no-preference) {
  /* Scroll run = height − the 100svh stage. 140svh until 2026-11-13, then 1.5× as fast (the user: 「這段頁面，滾動的速度加快1.5倍」). */
  .w-mod-js .mega-about-hero { height: calc(100svh + 140svh / 1.5); }
  .w-mod-js .mega-about-hero-stage { position: sticky; top: 0; height: 100svh; }
  .w-mod-js .mega-about-hero-content { display: grid; align-items: center; justify-items: start; }
  .w-mod-js .mega-about-hero-content > * { grid-area: 1 / 1; }
  .w-mod-js .mega-about-hero .about-hero_heading { transform: translate3d(0, calc(var(--about-hero-out, 0) * -6svh), 0); }
  .w-mod-js .mega-about-hero-statement { transform: translate3d(0, calc((1 - var(--about-hero-in, 0)) * 6svh), 0); }
  .w-mod-js .mega-about-hero:not(.is-scene-ready) .mega-about-hero-statement { visibility: hidden; }
}
@media (max-width: 991px) {
  .mega-about-hero-stage { min-height: min(100svh, 78vw); }
}
@media (max-width: 767px) {
  .mega-about-hero-stage { grid-template-columns: 1fr; min-height: 0; }
  .mega-about-hero-media { height: 62svh; min-height: 22rem; }
  .mega-about-hero-content { gap: 2rem; padding: 3.5rem clamp(16px, 5vw, 30px) 0; }
  .mega-about-hero .about-hero_heading .display-01 { font-size: min(18vw, 6rem); }
  .mega-about-hero-statement { font-size: min(8vw, 2.25rem); }
}
@media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
  .w-mod-js .mega-about-hero-stage { grid-template-rows: minmax(0, 3fr) minmax(max-content, 2fr); }
  .w-mod-js .mega-about-hero-media { height: auto; min-height: 0; }
  .w-mod-js .mega-about-hero-content { padding: 2rem clamp(16px, 5vw, 30px); }
}
/* The awards scene follows the about hero directly: no top margin, and no slide-in (it starts at opacity 0), so no black band shows between them. */
.page-wrapper:has(.mega-about-hero) .section-award { margin-top: 0; }
.page-wrapper:has(.mega-about-hero) .award-container { opacity: 1 !important; transform: none !important; }
/* Awards headings (Chinese): Noto Sans TC Black, 80px desktop / 60px phone, vertically centred on the left page margin.
   keep-all + <wbr> in the markup: one line when it fits, otherwise break only at the marked phrase boundaries.
   The top bar stays at the top (Webflow centres the container's content below 992px). */
.section-award .container.award { justify-content: flex-start; }
.section-award .award-bottom-wrap { position: absolute; top: 50%; right: 0; left: 0; transform: translateY(-50%); }
.section-award .award-title-wrap { align-items: flex-start; }
.section-award .award-title-wrap .display-02 { margin: 0; font: 900 80px/1.2 var(--mega-font); letter-spacing: 0; text-align: left; word-break: keep-all; overflow-wrap: anywhere; }
@media (max-width: 767px) {
  /* 60px, eased down on phones narrower than 392px so a six-character line still fits inside the 16px page margins. */
  .section-award .award-title-wrap .display-02 { font-size: min(60px, calc((100vw - 34px) / 6)); }
}
/* Awards backgrounds: photo at 50% saturation, then a 50% #98982A layer; Webflow's 20% black .dark-bg stays on top for the headings. */
.section-award img.award-image { z-index: 0; filter: saturate(.5); }
.section-award div.award-image::after { position: absolute; z-index: 1; inset: 0; content: ''; background: #98982a; opacity: .5; pointer-events: none; }
.section-award div.award-image .dark-bg { z-index: 2; }
/* About timeline (發展歷程) as a horizontal strip: the years run left to right from 2019, one slide each — the crystal year, then the
   olive line with a dot on it, then the event (centred, the spec's subtitle size). The strip spans the whole screen width (the section
   clips the scrollbar's few px past the edge, and its ends fade out) and starts with 2019 in the middle; swiping or scrolling sideways
   snaps the next year to the middle (scroll snap; site-navigation.js adds mouse drag, click-to-centre and the arrow keys). Only the
   middle year (.is-current) is lit; the others are dimmed. The line runs from the first dot to the last one. */
section:has(.experience-wrap) { overflow-x: clip; }
.experience-wrap {
  --slide-w: clamp(18rem, 32vw, 28rem);
  display: flex; width: 100vw; margin-left: calc(50% - 50vw); padding: 1.5rem 0 .5rem; box-sizing: border-box;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  outline: none;
}
.experience-wrap::-webkit-scrollbar { display: none; }
.experience-wrap:focus-visible .experience-item.is-current .experiencr-year { outline: 1px solid rgba(220, 232, 163, .6); outline-offset: 8px; }
.experience-wrap.is-dragging { scroll-snap-type: none; }
/* Spacers so the first and last slides can reach the middle. */
.experience-wrap::before, .experience-wrap::after { flex: 0 0 calc(50% - var(--slide-w) / 2); content: ''; }
/* Content from the top of each slide (Webflow centres it), so the years and the line sit level however long each event is. */
.experience-wrap .experience-item { flex: 0 0 var(--slide-w); justify-content: flex-start; gap: 0; margin: 0; padding: 0; border: 0; scroll-snap-align: center; }
/* The side years and their events are dimmed; the line and dots are not (they have their own falloff, below). */
.experience-wrap .experiencr-year, .experience-wrap .experience-position .body-text-2 { opacity: .3; transition: opacity .5s ease; }
.experience-wrap .experience-item.is-current .experiencr-year, .experience-wrap .experience-item.is-current .experience-position .body-text-2 { opacity: 1; }
.experience-wrap .experience-item > .flex-stretch:not(.phone) { flex-direction: column; align-items: center; gap: 0; }
.experience-wrap .experience-position { position: relative; align-self: stretch; padding: 4.25rem 1.25rem 0; }
.experience-wrap .experience-position .body-text-2 { font-size: var(--mega-subtitle); line-height: 1.5; text-align: center; }
/* The line fades from the middle of the strip towards both sides: site-navigation.js gives each slide five stops of that falloff
   along its segment (--line-0…4) and its dot the value at its centre (--dot). Each dot is one flat solid colour, no glow: the olive
   mixed with the ground rather than see-through, so the line does not show through it. */
.experience-wrap .experience-position::before { position: absolute; top: 1.75rem; right: 0; left: 0; height: 2px; margin-top: -1px; content: '';
  background: linear-gradient(90deg, rgb(152 152 42 / var(--line-0, 1)), rgb(152 152 42 / var(--line-1, 1)) 25%, rgb(152 152 42 / var(--line-2, 1)) 50%, rgb(152 152 42 / var(--line-3, 1)) 75%, rgb(152 152 42 / var(--line-4, 1))); }
.experience-wrap .experience-item:first-child .experience-position::before { left: 50%; }
.experience-wrap .experience-item:last-child .experience-position::before { right: 50%; }
.experience-wrap .experience-position::after { position: absolute; top: 1.75rem; left: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; content: '';
  background: #98982a; background: color-mix(in srgb, #98982a calc(var(--dot, 1) * 100%), var(--mega-bg)); }
@media (max-width: 767px) { .experience-wrap { --slide-w: 70vw; } }
/* The 探索之旅 heading and the timeline under it sit in the centre of the page: Webflow's empty left column (15% + 10% gap) is dropped
   and the content column keeps its 75% width, centred (≤991px it is already full width). The heading is centred. */
.main-content:has(.experience-wrap) > .left-content, .main-content:has(.experience-wrap) > .blank-space { display: none; }
.main-content:has(.experience-wrap) { grid-template-columns: minmax(0, 75%); justify-content: center; }
.main-content:has(.experience-wrap) > h1 { text-align: center; }
@media (max-width: 991px) { .main-content:has(.experience-wrap) { grid-template-columns: minmax(0, 1fr); } }
/* No + ornament (Webflow's .flex-stretch.phone row) under each event. */
.experience-wrap .experience-item > .flex-stretch.phone { display: none; }
/* Phones (≤767px): the heading is left-aligned. */
@media (max-width: 767px) {
  .main-content:has(.experience-wrap) > h1 { text-align: left; }
}
/* The years are crystal-numeral images, all cropped to one shared box so every year sits at the same scale: 57.6% of the slide
   (72%, made 20% smaller). Their black becomes the ground #151615 through the lighten blend above. */
.experience-wrap .experiencr-year { position: relative; flex: none; width: max-content; }
.experience-wrap .mega-year-image { display: block; width: calc(var(--slide-w) * .576); height: auto; -webkit-user-drag: none; }
/* 「致力於…探索之旅。」 colour sweep (site-navigation.js): grey to the text colour one character after another, playing through slowly
   by itself once the heading is in view, no scrolling needed — each character takes 1s and starts --reveal-step after the one before
   (set so the whole heading takes 5s). */
.mega-reveal-char { color: #4f4f4f; transition: color 1s ease-in-out calc(var(--i) * var(--reveal-step, 130ms)); }
.is-revealed .mega-reveal-char { color: var(--mega-text); }
@media (prefers-reduced-motion: reduce) { .mega-reveal-char { transition: none; } }
/* .mega-phrase: Chinese text breaks only between phrases (no lone 「儀」 / split 「化學」 lines). Also needed for headings Webflow
   splits into per-character boxes for its scroll reveal, which lose CJK line-break rules (a lone 「。」 can start a line). */
.mega-phrase { display: inline-block; }

/* Page loader (site-loader.js, in every page's <head>): black from the first paint, a liquid light in the middle (drawn on the canvas by
   site-loader.js; it has no edge) and the share of the page loaded so far at its centre, in white. Sits under the custom cursor. Once
   the page has loaded (.is-done) the number goes, the light darkens to black in 2.4s and, from the first second, the black thins away
   over 2s, so the page surfaces as the light goes out. */
.mega-loader { position: fixed; inset: 0; z-index: 2147482000; display: grid; place-items: center; overflow: hidden; background: var(--mega-bg); color: var(--mega-text); transition: opacity 2s cubic-bezier(.45, 0, .55, 1) 1s, visibility 0s linear 3s; }
.mega-loader-light { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* Without WebGL: a plain soft glow. */
.mega-loader.no-light .mega-loader-light { background: radial-gradient(circle min(46vmin, 430px), #1f6bff, rgb(31 107 255 / .5) 38%, rgb(31 107 255 / .12) 72%, rgb(31 107 255 / 0)); transition: opacity 2.4s cubic-bezier(.45, 0, .55, 1); }
.mega-loader.no-light.is-done .mega-loader-light { opacity: 0; }
/* The number is 80% of H1 (38.4px; 28.8px on phones) and thin, the % beside it at the same size, centred together on the screen. The
   gaps between the characters are 3 times their own (about 0.09em, so 0.18em more). Letter spacing also comes after the last character,
   so as much again on the left keeps what is seen in the middle. A faint dark lens behind them keeps the white legible on the bright hues. */
.mega-loader-count { position: relative; isolation: isolate; padding-left: .18em; font-family: var(--mega-font); font-size: calc(var(--mega-h1) * .8); font-weight: 100; line-height: 1; letter-spacing: .18em; font-variant-numeric: tabular-nums; text-shadow: 0 0 .3em rgb(0 0 0 / .25); opacity: 0; transition: opacity .5s ease; }
.mega-loader-count::before { content: ""; position: absolute; z-index: -1; left: 50%; top: 50%; width: 4em; height: 4em; margin: -2em 0 0 -2em; border-radius: 50%; background: radial-gradient(closest-side, rgb(0 0 0 / .22), rgb(0 0 0 / .15) 45%, rgb(0 0 0 / .05) 75%, rgb(0 0 0 / 0)); }
.mega-loader.is-ready .mega-loader-count { opacity: 1; }
.mega-loader.is-done .mega-loader-count { opacity: 0; transition-duration: .4s; }
.mega-loader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
