@font-face { font-family:'Plus Jakarta Sans'; font-weight:400; src:url('fonts/jakarta-400.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; font-weight:500; src:url('fonts/jakarta-500.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; font-weight:600; src:url('fonts/jakarta-600.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; font-weight:700; src:url('fonts/jakarta-700.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; font-weight:800; src:url('fonts/jakarta-800.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Be Vietnam Pro'; font-weight:400; src:url('fonts/bevietnam-400.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Be Vietnam Pro'; font-weight:500; src:url('fonts/bevietnam-500.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Be Vietnam Pro'; font-weight:600; src:url('fonts/bevietnam-600.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'JetBrains Mono'; font-weight:500; src:url('fonts/jetbrainsmono-500.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'JetBrains Mono'; font-weight:600; src:url('fonts/jetbrainsmono-600.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Archivo Narrow'; font-weight:400; src:url('fonts/archivonarrow-400.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Archivo Narrow'; font-weight:600; src:url('fonts/archivonarrow-600.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Archivo Narrow'; font-weight:700; src:url('fonts/archivonarrow-700.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Cinzel'; font-weight:400; src:url('fonts/cinzel-400.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Cinzel'; font-weight:700; src:url('fonts/cinzel-700.woff2') format('woff2'); font-display:swap; }

:root{ --font-head:'Archivo Narrow',system-ui,sans-serif;
        --font-serif:'Cinzel',-apple-system,'PingFang TC','Noto Sans TC',serif;
        --font-mono:'JetBrains Mono',ui-monospace,monospace;
        --font-body:-apple-system,'PingFang TC','Noto Sans TC',system-ui,sans-serif; }

html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

/* ── Paper Trail 原語 ── */
/* IMPORTANT: .splt-paper::before mask MUST be separate from parent drop-shadow filters.
   CSS mask clips all shadow layers in the same rendering context, so shadows would disappear
   if moved to parent. Keep mask on ::before (z-index:-1), drop-shadow on parent only. */
.splt-paper{ position:relative; z-index:0;
  filter: drop-shadow(0 3px 0 var(--paper-edge)) drop-shadow(0 6px 0 var(--paper-edge2)) drop-shadow(0 14px 26px rgba(70,58,40,.22)); }
.splt-paper::before{ content:""; position:absolute; inset:0; z-index:-1; background:var(--surface);
  -webkit-mask:
    radial-gradient(circle at 6px 8px, transparent 5.6px, #000 6px) repeat-x top / 12px 12px,
    linear-gradient(#000,#000) no-repeat center / 100% calc(100% - 16px),
    radial-gradient(circle at 6px 4px, transparent 5.6px, #000 6px) repeat-x bottom / 12px 12px;
  mask:
    radial-gradient(circle at 6px 8px, transparent 5.6px, #000 6px) repeat-x top / 12px 12px,
    linear-gradient(#000,#000) no-repeat center / 100% calc(100% - 16px),
    radial-gradient(circle at 6px 4px, transparent 5.6px, #000 6px) repeat-x bottom / 12px 12px; }
.splt-paper-flat{ background:var(--surface); border-radius:3px;
  box-shadow:0 3px 0 var(--paper-edge), 0 6px 0 var(--paper-edge2), 0 14px 26px rgba(70,58,40,.22); }
.splt-grain::after{ content:""; position:absolute; inset:0; pointer-events:none; opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E"); }
.splt-perf{ position:relative; height:1px; margin:14px 0; }
.splt-perf::before{ content:""; position:absolute; left:7px; right:7px; top:0;
  border-top:1.5px dashed var(--border); }
.splt-perf i{ position:absolute; top:-7px; width:14px; height:14px; border-radius:50%;
  background:var(--bg); }
.splt-perf i:first-child{ left:-7px; } .splt-perf i:last-child{ right:-7px; }
.splt-stamp{ display:inline-block; transform:rotate(-13deg); border:2.5px solid var(--primary);
  border-radius:2px; padding:5px 9px; color:var(--primary); opacity:.72;
  font-family:var(--font-serif); font-weight:700; font-size:11px; letter-spacing:.22em; }
.splt-ink{ border-radius:2px; padding:8px 7px 7px; position:relative; overflow:hidden; color:var(--ink); }
.splt-ink::after{ content:""; position:absolute; inset:0; pointer-events:none; opacity:.5; mix-blend-mode:screen;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.6' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='60' height='60' filter='url(%23m)'/%3E%3C/svg%3E"); }
.splt-tear{ border-top:2px dashed var(--border); position:relative; margin:22px 0 18px; }
.splt-tear span{ position:absolute; top:-9px; left:50%; transform:translateX(-50%);
  background:var(--bg); padding:3px 7px; font-family:var(--font-mono); font-size:8px;
  letter-spacing:.2em; color:var(--muted); }
/* 郵票齒:只沿四邊挖孔,與 Android postageShape / iOS PostageShape 同源。
   舊版是 6px 網格鋪滿整個面 = 整片打洞,和另外兩端不同源(批 1 修)。
   四層邊緣遮罩 + 一層中央實心矩形;層與層之間預設 add(聯集)。 */
.splt-postage{
  -webkit-mask:
    radial-gradient(circle at 3px 0, transparent 2.4px, #000 2.6px) 0 0/6px 3px repeat-x,
    radial-gradient(circle at 3px 3px, transparent 2.4px, #000 2.6px) 0 100%/6px 3px repeat-x,
    radial-gradient(circle at 0 3px, transparent 2.4px, #000 2.6px) 0 0/3px 6px repeat-y,
    radial-gradient(circle at 3px 3px, transparent 2.4px, #000 2.6px) 100% 0/3px 6px repeat-y,
    linear-gradient(#000, #000) 3px 3px/calc(100% - 6px) calc(100% - 6px) no-repeat;
  mask:
    radial-gradient(circle at 3px 0, transparent 2.4px, #000 2.6px) 0 0/6px 3px repeat-x,
    radial-gradient(circle at 3px 3px, transparent 2.4px, #000 2.6px) 0 100%/6px 3px repeat-x,
    radial-gradient(circle at 0 3px, transparent 2.4px, #000 2.6px) 0 0/3px 6px repeat-y,
    radial-gradient(circle at 3px 3px, transparent 2.4px, #000 2.6px) 100% 0/3px 6px repeat-y,
    linear-gradient(#000, #000) 3px 3px/calc(100% - 6px) calc(100% - 6px) no-repeat;
}
.splt-barcode{ display:flex; gap:1.6px; align-items:flex-end; height:27px; }
.splt-barcode i{ display:block; width:2px; background:var(--ink); }

/* 舊 class:簽名保留、實作紙感中性版(批 N 清理) */
/* border-radius 用 !important:呼叫端普遍 inline 覆寫成 18-24px 圓角(Midnight Neon 時代殘留),
   Android/iOS 的 glassCard 已把 radius 參數 @Suppress 掉強制方角(紙感中性化),Web 若被 inline 蓋掉
   會變成同一張卡三端不一致(Android/iOS 方角、Web 圓角)。過渡期專用,批 N 連同 .splt-glass class 一併刪。 */
.splt-glass{ background:var(--surface); border-radius:3px !important;
  box-shadow:0 3px 0 var(--paper-edge), 0 6px 0 var(--paper-edge2), 0 14px 26px rgba(70,58,40,.22); }
.splt-grad{ background:var(--ink); color:var(--on-primary); }
.splt-glow{ box-shadow:none; }
.splt-press{ transition:transform .12s ease; }
.splt-press:active{ transform:translateY(1px); }

/* ── Task 14: 客製元件(取代平台預設) ── */
.splt-field{ background:transparent; border:none; outline:none; width:100%;
  border-bottom:1.5px dashed color-mix(in srgb, var(--ink) 35%, transparent);
  font-family:var(--font-body); font-size:15px; color:var(--ink); padding:4px 0 6px; }
.splt-field::placeholder{ color:var(--muted); }
.splt-field:focus{ border-bottom-color:color-mix(in srgb, var(--ink) 90%, transparent); }
.splt-toggle-input:focus-visible + .splt-toggle-box{ outline:2px solid var(--ink); outline-offset:2px; }

/* ── scan 取景窗(對齊 Android ScanScreen 的 ScanIdleView/CropMarks/ScanSweep) ── */
/* scan 取景窗:紙上挖穿的方窗,窗底是深墨桌面 */
/* border-radius 3px = SpltDimens.radiusCard(對齊 Android 取景區的 RoundedCornerShape(radiusCard)) */
.scan-vport{position:relative;overflow:hidden;border-radius:3px;
  background:color-mix(in srgb,var(--ink) 92%,#000);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5),inset 0 2px 10px rgba(0,0,0,.55);
  min-height:330px;display:grid;place-items:center;cursor:pointer}
/* 印刷裁切標記:四角 L 形。Web 窗底恆為深墨不受此問題影響,但三端同源加 ink 陰影
   (color-mix 55%)撐出對比 —— Android/iOS 是相機即時預覽,亮場景會蓋掉深墨底致 surface
   線條幾乎隱形,同形位移 1px 陰影讓亮/暗背景都讀得到。 */
.scan-crop{position:absolute;width:26px;height:26px;pointer-events:none}
.scan-crop::before,.scan-crop::after{content:"";position:absolute;background:var(--surface);opacity:.9;
  box-shadow:1px 1px 0 0 color-mix(in srgb,var(--ink) 55%,transparent)}
.scan-crop::before{width:26px;height:1.5px}
.scan-crop::after{width:1.5px;height:26px}
.scan-crop.tl{left:14px;top:14px}
.scan-crop.tr{right:14px;top:14px}.scan-crop.tr::before{right:0}.scan-crop.tr::after{right:0}
.scan-crop.bl{left:14px;bottom:14px}.scan-crop.bl::before{bottom:0}.scan-crop.bl::after{bottom:0}
.scan-crop.br{right:14px;bottom:14px}.scan-crop.br::before{right:0;bottom:0}.scan-crop.br::after{right:0;bottom:0}
/* 掃描光:同裁切標記,加 ink 陰影層撐出對比(見上方註解) */
.scan-sweep{position:absolute;left:0;right:0;height:1.5px;background:var(--surface);opacity:.6;
  box-shadow:0 1px 0 0 color-mix(in srgb,var(--ink) 50%,transparent),
             0 0 10px 0 color-mix(in srgb,var(--surface) 28%,transparent);
  animation:scan-sw 5.2s linear infinite;pointer-events:none}
/* 5.2s 是「來回」一圈 → 單程 2.6s、linear、距上下緣 14px,與 Android `tween(2600, LinearEasing)`
   + `RepeatMode.Reverse`(inset 14dp)/ iOS `.linear(duration: 2.6).repeatForever(autoreverses: true)`
   (inset 14pt)同源。舊寫法 2.6s 是整個來回 → 單程只有 1.3s,速度剛好是另兩端的兩倍。 */
@keyframes scan-sw{0%,100%{top:14px}50%{top:calc(100% - 14px)}}
/* SCANNING 步驟列的列印光標:8x14 墨塊,.9s 週期硬切明滅(對齊 Android tween(900) / iOS 0.45s toggle) */
.scan-caret{display:inline-block;width:8px;height:14px;background:var(--ink);
  transform:translateY(2px);animation:scan-bl .9s steps(1) infinite}
@keyframes scan-bl{0%,50%{opacity:1}51%,100%{opacity:0}}

/* 收據零件:點線 leader 與明細列底線(對齊 Android ReceiptParts.kt) */
.receipt-leader{ flex:1; margin:0 8px 5px; border-bottom:1.5px dotted var(--border); align-self:flex-end; }
.receipt-row{ border-bottom:1px dotted var(--border); }

@media (prefers-reduced-motion: reduce){ *{ animation:none !important; transition:none !important; } }