/* Wireframe system — editorial on white. Pure white paper, Fraunces display, Inter body, JetBrains Mono labels, single terracotta accent #c4553a. */ :root { --ink: #0f0f0e; --ink-2: #1c1c1b; --ink-3: #6a6a68; --ink-4: #a4a4a1; --line: #ebebeb; --line-2: #d6d6d4; --control-line: #858581; --paper: #ffffff; --paper-2: #f6f6f4; --paper-3: #ededea; --card: #ffffff; --accent: #c4553a; --accent-soft: #f5e4de; --ok: #2f6848; --ok-soft: #e4ecde; --warn: #9a7820; --warn-soft: #f2e8cf; --bad: #9c3b35; --bad-soft: #f2dcd6; --f-serif: "Fraunces", "Instrument Serif", "Cormorant Garamond", Georgia, serif; --f-sans: "Inter", system-ui, -apple-system, sans-serif; --f-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; } * { box-sizing: border-box; } html, body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--f-sans); font-weight: 400; font-size: 14px; line-height: 1.55; -webkit-font-smoothing: antialiased; letter-spacing: -0.003em; } .ui { font-family: var(--f-sans); } .mono { font-family: var(--f-mono); font-feature-settings: "ss01"; } /* legacy .title / .hand used by markup → serif display / sans emphasis */ .title { font-family: var(--f-serif) !important; font-weight: 400; letter-spacing: -0.015em; line-height: 1.05; } .hand { font-family: var(--f-sans) !important; font-weight: 500; letter-spacing: -0.005em; } /* uppercase mono label */ .label, .kicker { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); font-weight: 400; } /* ===== Global shell ===== */ .shell { max-width: 1440px; margin: 0 auto; padding: 48px 40px 140px; } .shell-head { display: grid; grid-template-columns: 1.3fr 1fr; gap: 48px; padding-bottom: 32px; margin-bottom: 40px; border-bottom: 1px solid var(--line); align-items: flex-end; } .shell-head .crumb { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--ink-3); text-transform: uppercase; margin-bottom: 10px; } .shell-head h1 { font-family: var(--f-serif); font-size: 72px; font-weight: 400; margin: 0; line-height: 0.95; letter-spacing: -0.025em; } .shell-head h1 em { font-style: italic; color: var(--accent); } .shell-head .meta { font-size: 13px; color: var(--ink-2); line-height: 1.65; max-width: 420px; } /* ===== Tab bar ===== */ .tabbar { position: sticky; top: 0; z-index: 30; background: var(--paper); border-bottom: 1px solid var(--line); padding: 14px 0; display: flex; gap: 2px; overflow-x: auto; margin: 0 0 40px; } .tabbar::-webkit-scrollbar { height: 0; } .tab { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 400; background: transparent; border: none; padding: 6px 12px; cursor: pointer; white-space: nowrap; color: var(--ink-3); transition: color .12s; position: relative; } .tab:hover { color: var(--ink); } .tab.active { color: var(--ink); font-weight: 500; } .tab.active::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -14px; height: 2px; background: var(--accent); } .tab small { font-size: 8px; font-weight: 400; margin-left: 6px; color: var(--accent); letter-spacing: 0.12em; vertical-align: 1px; } /* ===== Screen ===== */ .screen { display: none; } .screen.active { display: block; } .screen-intro { display: grid; grid-template-columns: 1.2fr 1fr; gap: 56px; padding: 0 0 40px; margin-bottom: 48px; border-bottom: 1px solid var(--line); } .screen-intro h2 { font-family: var(--f-serif); margin: 0 0 14px; font-size: 48px; font-weight: 400; line-height: 1; letter-spacing: -0.02em; } .screen-intro p { margin: 0; color: var(--ink-2); font-size: 15px; line-height: 1.7; max-width: 520px; } .screen-intro .goals { padding-top: 8px; font-size: 12px; color: var(--ink-2); line-height: 1.8; } .screen-intro .goals > div { padding: 6px 0; border-bottom: 1px solid var(--line); display: grid; grid-template-columns: 24px 1fr; gap: 8px; align-items: baseline; } .screen-intro .goals > div:last-child { border-bottom: 0; } .screen-intro .goals > div::before { content: counter(goal, decimal-leading-zero); counter-increment: goal; font-family: var(--f-mono); font-size: 10px; color: var(--accent); letter-spacing: 0.1em; } .screen-intro .goals { counter-reset: goal; } .screen-intro .goals b { color: var(--ink); font-weight: 500; } /* ===== Variations grid ===== */ .vars { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; margin-bottom: 48px; } .vars.vars-wide { grid-template-columns: 1fr; gap: 56px; } @media (max-width: 1100px) { .vars { grid-template-columns: 1fr; } } .var { display: flex; flex-direction: column; gap: 16px; } .var-label { display: flex; align-items: baseline; gap: 14px; padding: 0 0 12px; border-bottom: 1px solid var(--line); } .var-label .tag { font-family: var(--f-serif); font-size: 42px; line-height: 1; font-style: italic; color: var(--accent); font-weight: 400; letter-spacing: -0.03em; } .var-label .name { font-family: var(--f-sans); font-size: 14px; font-weight: 500; color: var(--ink); letter-spacing: -0.005em; } .var-label .hint { font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); margin-left: auto; text-align: right; line-height: 1.5; max-width: 260px; letter-spacing: 0.03em; } /* ===== Phone frame ===== */ .phone { background: var(--ink); border-radius: 42px; padding: 8px; box-shadow: 0 0 0 1px var(--line), 0 24px 48px -16px rgba(13,13,13,0.25), 0 4px 12px -4px rgba(13,13,13,0.15); position: relative; } .phone::before { content: ""; position: absolute; top: 18px; left: 50%; transform: translateX(-50%); width: 96px; height: 26px; background: var(--ink); border-radius: 14px; z-index: 2; } .phone-screen { background: var(--card); border-radius: 34px; overflow: hidden; aspect-ratio: 375 / 780; position: relative; display: flex; flex-direction: column; } .phone-status { font-family: var(--f-sans); font-size: 11px; padding: 14px 26px 6px; display: flex; justify-content: space-between; color: var(--ink); font-weight: 600; letter-spacing: 0; } .phone-status .notch-space { width: 110px; } /* ===== Inner building blocks ===== */ .w-body { flex: 1; padding: 14px 18px 18px; display: flex; flex-direction: column; gap: 14px; overflow: hidden; } .w-topbar { display: flex; justify-content: space-between; align-items: center; padding: 4px 2px 12px; border-bottom: 1px solid var(--line); } .w-topbar .logo { font-family: var(--f-serif); font-size: 22px; line-height: 1; font-style: italic; letter-spacing: -0.02em; } .w-topbar .icons { display: flex; gap: 4px; } .w-icon { width: 28px; height: 28px; border: 1px solid var(--line); border-radius: 2px; display: grid; place-items: center; font-size: 13px; color: var(--ink-2); background: transparent; } .w-h { font-family: var(--f-serif); font-size: 26px; font-weight: 400; line-height: 1.05; letter-spacing: -0.02em; margin: 2px 0; } .w-sub { font-size: 12px; color: var(--ink-3); line-height: 1.55; } .w-txt { font-size: 13px; color: var(--ink-2); line-height: 1.6; } /* cards — sharp corners, 1px hairline */ .w-card { border: 1px solid var(--line); border-radius: 2px; padding: 14px; background: var(--card); } .w-card.soft { background: var(--paper-2); border-color: var(--line); } .w-card.hi { background: var(--accent-soft); border-color: #e3c7c2; } /* placeholder */ .w-ph { background: var(--paper-2); border: 1px solid var(--line); border-radius: 2px; display: grid; place-items: center; font-family: var(--f-mono); font-size: 9px; color: var(--ink-4); text-transform: uppercase; letter-spacing: 0.12em; text-align: center; padding: 6px; position: relative; } .w-ph::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom right, transparent 49.5%, var(--line) 49.5%, var(--line) 50.5%, transparent 50.5%), linear-gradient(to bottom left, transparent 49.5%, var(--line) 49.5%, var(--line) 50.5%, transparent 50.5%); opacity: .4; pointer-events: none; } /* actions */ .w-actions { display: flex; gap: 8px; margin-top: auto; padding-top: 10px; } .w-btn { flex: 1; min-height: 44px; border: 1px solid var(--ink); border-radius: 2px; padding: 11px 14px; text-align: center; font-family: var(--f-sans); font-size: 12px; background: transparent; font-weight: 500; color: var(--ink); cursor: pointer; letter-spacing: 0.01em; transition: background .12s; } .w-btn.primary { background: var(--ink); color: var(--card); } .w-btn.accent { background: var(--accent); color: var(--card); border-color: var(--accent); } .w-btn.ghost { border-color: transparent; color: var(--ink-2); } .w-chip { border: 1px solid var(--line-2); border-radius: 2px; padding: 3px 8px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.04em; display: inline-flex; align-items: center; gap: 4px; background: transparent; color: var(--ink-2); line-height: 1.5; font-weight: 400; } .w-chip.ok { background: var(--ok-soft); color: var(--ok); border-color: #b9ccab; } .w-chip.warn { background: var(--warn-soft); color: var(--warn); border-color: #d6c28a; } .w-chip.bad { background: var(--bad-soft); color: var(--bad); border-color: #d5b4ae; } /* score — large serif number */ .w-score { --sc: var(--ok); width: 76px; height: 76px; border-radius: 50%; border: 1.5px solid var(--sc); display: grid; place-items: center; font-family: var(--f-serif); font-size: 34px; font-weight: 400; line-height: 1; color: var(--ink); background: transparent; letter-spacing: 0; } .w-score.big { width: 92px; height: 92px; font-size: 40px; border-width: 2px; } .w-score.sm { width: 48px; height: 48px; font-size: 20px; border-width: 1.2px; } .w-score.warn { --sc: var(--warn); } .w-score.bad { --sc: var(--bad); } /* bar — hairline */ .w-bar { height: 2px; background: var(--line); overflow: hidden; } .w-bar i { display: block; height: 100%; background: var(--ok); } .w-bar i.warn { background: var(--warn); } .w-bar i.bad { background: var(--bad); } /* ingredient row */ .ing { display: grid; grid-template-columns: 14px 1fr auto; gap: 12px; align-items: center; padding: 10px 2px; border-bottom: 1px solid var(--line); } .ing:last-child { border-bottom: 0; } .ing .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); justify-self: center; } .ing .dot.warn { background: var(--warn); } .ing .dot.bad { background: var(--bad); } .ing .n { font-size: 13px; font-weight: 400; color: var(--ink); letter-spacing: -0.005em; } .ing .m { font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); margin-top: 2px; letter-spacing: 0.02em; } .ing .r { font-family: var(--f-serif); font-size: 18px; font-style: italic; color: var(--ink-3); font-weight: 400; } /* rows */ .row { display: flex; align-items: center; justify-content: space-between; padding: 10px 2px; border-bottom: 1px solid var(--line); font-size: 12px; } .row:last-child { border-bottom: 0; } /* bottom tabs */ .w-tabbar { display: flex; justify-content: space-around; border-top: 1px solid var(--line); padding: 10px 4px 6px; margin: 0 -18px -18px; background: var(--card); } .w-tabbar .ti { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-4); display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 2px 0; } .w-tabbar .ti.on { color: var(--ink); } .w-tabbar .ti span:first-child { width: 22px; height: 22px; display: grid; place-items: center; font-size: 15px; font-family: var(--f-sans); } /* notes */ .notes { margin-top: 40px; padding-top: 32px; border-top: 1px solid var(--line); display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; } @media (max-width: 1100px) { .notes { grid-template-columns: 1fr; } } .notes h4 { font-family: var(--f-mono); margin: 0 0 12px; font-size: 10px; font-weight: 400; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); } .notes p, .notes li { font-size: 12.5px; color: var(--ink-2); line-height: 1.75; margin: 0 0 6px; } .notes ul { padding-left: 14px; margin: 0; } .notes ul li::marker { color: var(--accent); font-family: var(--f-mono); font-size: 10px; } /* ===== Tweaks panel ===== */ .tweaks { position: fixed; right: 24px; bottom: 24px; width: 300px; background: var(--card); border: 1px solid var(--ink); border-radius: 2px; z-index: 50; font-size: 12px; display: none; box-shadow: 0 12px 32px -8px rgba(13,13,13,0.25); } .tweaks.open { display: block; } .tweaks-head { display: flex; justify-content: space-between; align-items: center; padding: 14px 18px; border-bottom: 1px solid var(--line); } .tweaks-head h3 { margin: 0; font-family: var(--f-serif); font-size: 22px; font-style: italic; font-weight: 400; letter-spacing: -0.02em; } .tweaks-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 18px; } .tweaks-group label { display: block; font-family: var(--f-mono); margin-bottom: 8px; font-size: 10px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.12em; } .tweaks-group .opts { display: flex; gap: 4px; flex-wrap: wrap; } .tweaks-group .opts button { font-family: var(--f-sans); font-size: 11px; padding: 4px 10px; border: 1px solid var(--line-2); border-radius: 2px; background: transparent; cursor: pointer; color: var(--ink-2); } .tweaks-group .opts button.on { background: var(--ink); color: var(--card); border-color: var(--ink); } /* density */ body[data-density="minimal"] .phone-screen .w-card:not(.keep) { padding: 10px; } body[data-density="minimal"] .phone-screen .ing { padding: 6px 2px; } body[data-density="dense"] .phone-screen .w-body { gap: 10px; } body[data-density="dense"] .phone-screen .w-card { padding: 10px; } /* alts/src/order toggles */ body[data-alts="chips"] .alts-grid, body[data-alts="chips"] .alts-inline { display: none !important; } body[data-alts="chips"] .alts-chips { display: flex !important; } body[data-alts="grid"] .alts-chips, body[data-alts="grid"] .alts-inline { display: none !important; } body[data-alts="grid"] .alts-grid { display: grid !important; } body[data-alts="inline"] .alts-chips, body[data-alts="inline"] .alts-grid { display: none !important; } body[data-alts="inline"] .alts-inline { display: block !important; } body[data-src="footer"] .src-badge, body[data-src="footer"] .src-expand { display: none !important; } body[data-src="footer"] .src-footer { display: block !important; } body[data-src="badge"] .src-footer, body[data-src="badge"] .src-expand { display: none !important; } body[data-src="badge"] .src-badge { display: inline-flex !important; } body[data-src="expand"] .src-footer, body[data-src="expand"] .src-badge { display: none !important; } body[data-src="expand"] .src-expand { display: block !important; } .block-top{order:0}.block-score,.block-prod,.block-ing,.block-alts{order:20}.block-src{order:90}.block-cta{order:95}.block-foot{order:99} body[data-order="score"] .block-score{order:10} body[data-order="score"] .block-prod{order:11} body[data-order="score"] .block-ing{order:12} body[data-order="score"] .block-alts{order:13} body[data-order="product"] .block-prod{order:10} body[data-order="product"] .block-score{order:11} body[data-order="product"] .block-ing{order:12} body[data-order="product"] .block-alts{order:13} body[data-order="ing"] .block-ing{order:10} body[data-order="ing"] .block-score{order:11} body[data-order="ing"] .block-prod{order:12} body[data-order="ing"] .block-alts{order:13} .tweaks-fab { position: fixed; right: 24px; bottom: 24px; background: var(--ink); color: var(--card); border: none; border-radius: 2px; padding: 10px 18px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer; z-index: 49; display: none; } body.tweaks-available .tweaks-fab { display: block; } body.tweaks-available .tweaks.open + .tweaks-fab { display: none; } /* ===== Desktop landing frame ===== */ .desk { background: var(--card); border: 1px solid var(--ink); border-radius: 2px; overflow: hidden; } .desk-chrome { background: var(--paper-2); border-bottom: 1px solid var(--line); padding: 10px 14px; display: flex; align-items: center; gap: 6px; } .d-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); } .d-url { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.04em; color: var(--ink-3); margin-left: 14px; background: var(--card); border: 1px solid var(--line); padding: 3px 12px; border-radius: 2px; } .desk-screen { background: var(--card); } .ls-nav { display: flex; justify-content: space-between; align-items: center; padding: 22px 40px; border-bottom: 1px solid var(--line); } .ls-block { padding: 48px 40px; border-top: 1px solid var(--line); } .ls-block-head { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 28px; gap: 24px; } .ls-cards-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; } .ls-cards-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; } .ls-two { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; padding: 40px; align-items: flex-start; } .fasie { display: flex; align-items: flex-start; gap: 14px; } .fasie-logo { width: 56px; height: 56px; border: 1px solid currentColor; border-radius: 2px; display: grid; place-items: center; flex-shrink: 0; background: transparent; font-family: var(--f-serif); font-size: 18px; font-style: italic; font-weight: 400; } /* ===== Admin panel ===== */ .admin-wire { display: grid; grid-template-columns: 340px 1fr; gap: 40px; align-items: flex-start; } @media (max-width: 900px) { .admin-wire { grid-template-columns: 1fr; } } .admin-left, .admin-right { min-width: 0; } .admin-panel-mock { background: var(--card); border: 1px solid var(--ink); border-radius: 2px; padding: 28px; } .admin-panel-head { display: flex; justify-content: space-between; align-items: flex-start; padding-bottom: 20px; border-bottom: 1px solid var(--ink); margin-bottom: 24px; } .adm-block { border: 1px solid var(--line); padding: 18px; margin-bottom: 16px; background: transparent; } .adm-block-head { display: flex; justify-content: space-between; align-items: center; padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px solid var(--line); } .adm-field { margin-bottom: 14px; } .adm-input { font-family: var(--f-mono); font-size: 11px; background: var(--paper-2); border: 1px solid var(--line); padding: 8px 12px; color: var(--ink-2); word-break: break-all; } .adm-metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px; } .adm-metric { display: flex; justify-content: space-between; align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 12px; } .adm-metric span { color: var(--ink-3); font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; } .adm-metric code { font-family: var(--f-mono); font-size: 12px; color: var(--ink); } .adm-metric code.ok { color: var(--ok); } .adm-metric code.warn { color: var(--warn); } .adm-metric code.bad { color: var(--bad); } .adm-accordion { margin-top: 12px; border-top: 1px solid var(--line); } .adm-ac-row { padding: 10px 2px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; border-bottom: 1px solid var(--line); color: var(--ink-2); } .adm-ac-body { padding: 10px 2px 12px; border-bottom: 1px solid var(--line); } .adm-line { font-family: var(--f-mono); font-size: 11px; color: var(--ink-2); padding: 2px 0; } .adm-log { background: var(--ink); color: var(--paper); padding: 14px 16px; font-family: var(--f-mono); font-size: 11px; line-height: 1.8; } .adm-log-line.ok { color: #9ecfa3; } .adm-log-line .adm-ts { color: rgba(244,239,228,0.4); margin-right: 10px; } .adm-net { display: flex; flex-direction: column; } .adm-net-row { display: grid; grid-template-columns: 60px 1fr 50px 60px; gap: 16px; align-items: center; font-family: var(--f-mono); font-size: 11px; padding: 10px 0; border-bottom: 1px solid var(--line); } .adm-method { font-size: 9px; font-weight: 500; padding: 2px 6px; letter-spacing: 0.1em; text-align: center; } .adm-method.post { color: var(--accent); border: 1px solid var(--accent); } .adm-method.get { color: var(--ink-3); border: 1px solid var(--line-2); } .adm-path { color: var(--ink); } .adm-status { font-size: 11px; text-align: center; } .adm-status.ok { color: var(--ok); } .adm-status.warn { color: var(--warn); } .adm-status.bad { color: var(--bad); } .adm-ms { color: var(--ink-3); text-align: right; } /* ===== Stores ===== */ .store-row { border: 1px solid var(--line); padding: 14px; background: transparent; } .store-row.winner { border: 1px solid var(--ink); background: var(--card); position: relative; } .store-row.winner::before { content: "BEST"; position: absolute; top: -1px; right: -1px; background: var(--accent); color: var(--card); font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.15em; padding: 3px 8px; } .store-row.plan { opacity: .55; background: var(--paper-2); } .store-row-head { display: flex; gap: 12px; align-items: center; } .store-logo { width: 36px; height: 36px; border: 1px solid var(--ink); border-radius: 2px; display: grid; place-items: center; font-family: var(--f-mono); font-weight: 500; font-size: 11px; letter-spacing: 0.04em; flex-shrink: 0; background: var(--card); } .store-logo.sm { width: 28px; height: 28px; font-size: 10px; } .store-logo.ga { background: var(--ink); color: #e8c960; border-color: var(--ink); } .store-logo.pod { background: #d0466e; color: var(--card); border-color: #d0466e; } .store-logo.let { background: var(--ink); color: #d9b362; border-color: var(--ink); } .store-logo.wb { background: #b11095; color: var(--card); border-color: #b11095; } .store-logo.oz { background: #0047d1; color: var(--card); border-color: #0047d1; } .sparkline { margin-top: 10px; display: flex; align-items: center; gap: 10px; } .sparkline svg { flex: 1; height: 24px; display: block; } .store-compact { display: flex; gap: 12px; align-items: center; padding: 12px 14px; border: 1px solid var(--line); background: transparent; font-size: 13px; } .store-compact.ok { border-color: var(--ink); background: var(--card); } .store-compact.plan { opacity: .55; background: var(--paper-2); } /* ===== Candidate ===== */ .cand { display: flex; gap: 12px; align-items: flex-start; padding: 12px; border: 1px solid var(--line); background: transparent; } .cand.sel { border: 1px solid var(--accent); background: var(--card); } .cand > .w-ph { width: 64px; flex-shrink: 0; } .cand-stack { position: absolute; left: 0; right: 0; border: 1px solid var(--line); background: var(--card); } .cand-stack.s1 { top: 0; bottom: 0; z-index: 3; padding: 10px; border-color: var(--ink); } .cand-stack.s2 { top: 8px; bottom: -8px; left: 10px; right: 10px; z-index: 2; background: var(--paper-2); } .cand-stack.s3 { top: 16px; bottom: -16px; left: 20px; right: 20px; z-index: 1; background: var(--paper-3); opacity: .6; } .big-btn { width: 60px; height: 60px; border-radius: 50%; border: 1px solid var(--ink); display: grid; place-items: center; font-size: 20px; background: transparent; color: var(--ink); } .big-btn.accent { background: var(--accent); color: var(--card); border-color: var(--accent); } /* telegram */ .tg-msg { max-width: 78%; border-radius: 12px; padding: 10px 14px; font-size: 12px; line-height: 1.55; margin-bottom: 8px; font-family: var(--f-sans); } .tg-msg.bot { background: #fff; color: #222; border-top-left-radius: 4px; } .tg-msg.me { background: #e1f5b5; color: #222; border-top-right-radius: 4px; margin-left: auto; } @keyframes pulse { 0%,100%{transform:scale(1); opacity:1} 50%{transform:scale(1.18); opacity:.65} } @keyframes spin { to { transform: rotate(360deg); } } .annot { font-family: var(--f-serif); font-style: italic; font-size: 13px; color: var(--ink-3); padding: 4px 0; } .annot::before { content: "— "; } /* swap the hero's "BIG TEXT centered" into editorial layout helpers */ .edit-pull { font-family: var(--f-serif); font-size: 96px; line-height: 0.9; letter-spacing: -0.035em; font-weight: 400; margin: 0; } .edit-pull em { font-style: italic; color: var(--accent); } .edit-rule { border: 0; border-top: 1px solid var(--ink); margin: 0; } /* === APPENDED PROD EXTRAS v4 === */ /* === .hidden missing from archive === */ .hidden { display: none !important; } [hidden] { display: none !important; } /* === Production shell — NOT the wireframe explorer shell === */ .prod-header { position: sticky; top: 0; z-index: 30; background: var(--paper); border-bottom: 1px solid var(--line); } .prod-header__inner { max-width: 1100px; margin: 0 auto; padding: 20px 32px; display: grid; grid-template-columns: auto 1fr; gap: 40px; align-items: center; } .prod-brand { text-decoration: none; color: inherit; display: flex; align-items: baseline; gap: 10px; } .prod-brand .b-mark { font-family: var(--f-serif); font-weight: 400; font-size: 22px; font-style: italic; letter-spacing: -0.02em; line-height: 1; color: var(--accent); } .prod-brand .b-name { font-family: var(--f-serif); font-weight: 400; font-size: 20px; letter-spacing: -0.02em; line-height: 1; } .prod-nav { display: flex; gap: 4px; justify-content: flex-end; flex-wrap: wrap; } .prod-nav a { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); text-decoration: none; padding: 6px 10px; border: 1px solid transparent; transition: color .12s, border-color .12s; } .prod-nav a:hover { color: var(--ink); } .prod-nav a.active { color: var(--accent); border-bottom: 1px solid var(--accent); } @media (max-width: 720px) { .prod-header__inner { grid-template-columns: 1fr; gap: 12px; padding: 16px 20px; } .prod-nav { justify-content: flex-start; } } /* page containers */ .prod-page { max-width: 860px; margin: 0 auto; padding: 40px 32px 120px; } .prod-page-wide { max-width: 1100px; margin: 0 auto; padding: 40px 32px 120px; } @media (max-width: 640px) { .prod-page, .prod-page-wide { padding: 20px 16px 80px; } } /* === Editorial headline block === */ .ed-kicker { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-3); display: inline-flex; align-items: center; gap: 12px; } .ed-kicker::before, .ed-kicker::after { content: ""; width: 28px; height: 1px; background: var(--ink-3); } .ed-kicker.one-sided::before { display: none; } .ed-display { font-family: var(--f-serif); font-weight: 400; font-size: clamp(44px, 7.5vw, 96px); line-height: 0.98; letter-spacing: -0.028em; margin: 20px 0 14px; max-width: 16ch; color: var(--ink); } .ed-display em { font-style: italic; color: var(--accent); } .ed-lead { font-family: var(--f-serif); font-weight: 400; font-size: 20px; font-style: italic; color: var(--ink-2); line-height: 1.5; max-width: 46ch; margin: 0; letter-spacing: -0.005em; } /* Drop cap for long paragraphs */ .ed-drop::first-letter { font-family: var(--f-serif); font-size: 60px; line-height: 0.9; float: left; padding: 4px 10px 0 0; font-weight: 400; color: var(--accent); font-style: italic; } /* Numbered section header */ .ed-section { border-top: 1px solid var(--line); padding-top: 40px; margin-top: 56px; display: grid; grid-template-columns: 100px 1fr; gap: 32px; align-items: baseline; } .ed-section > .num { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.18em; color: var(--accent); } .ed-section > .head { font-family: var(--f-serif); font-size: 36px; line-height: 1; letter-spacing: -0.02em; font-weight: 400; margin: 0; } .ed-section > .content { grid-column: 2; margin-top: 16px; } @media (max-width: 640px) { .ed-section { grid-template-columns: 1fr; gap: 4px; } .ed-section > .content { grid-column: 1; } .ed-section > .head { font-size: 28px; } } /* 3/4-col info cards with asymmetric breakpoint */ .ed-cards-3 { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 32px; } .ed-cards-4 { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: 28px; } @media (max-width: 720px) { .ed-cards-3, .ed-cards-4 { grid-template-columns: 1fr; gap: 20px; } } .ed-card { padding-top: 14px; border-top: 1px solid var(--ink); } .ed-card .num { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--ink-3); display: block; margin-bottom: 8px; } .ed-card h4 { font-family: var(--f-serif); font-weight: 400; font-size: 22px; line-height: 1.1; letter-spacing: -0.01em; margin: 0 0 6px; max-width: 18ch; } .ed-card p { font-family: var(--f-sans); font-size: 13px; line-height: 1.65; color: var(--ink-2); margin: 0; max-width: 36ch; } /* Buttons — editorial, no rounded */ .ed-btn { display: inline-flex; align-items: center; gap: 8px; padding: 14px 22px; font-family: var(--f-sans); font-weight: 500; font-size: 13px; letter-spacing: 0.02em; border: 1px solid var(--ink); background: var(--ink); color: var(--card); text-decoration: none; cursor: pointer; transition: background .12s, color .12s; } .ed-btn.primary { background: var(--accent); color: var(--card); border-color: var(--accent); } .ed-btn.primary:hover { background: transparent; color: var(--accent); } .ed-btn.ghost { background: transparent; color: var(--ink); } .ed-btn.ghost:hover { background: var(--ink); color: var(--card); } .ed-btn .arrow { font-family: var(--f-serif); font-style: italic; font-size: 16px; } /* === Scanner entry (variant C with editorial treatment) === */ .scan-hero { display: grid; grid-template-columns: 1.3fr 1fr; gap: 40px; align-items: end; padding: 40px 0 28px; border-bottom: 1px solid var(--line); } @media (max-width: 720px) { .scan-hero { grid-template-columns: 1fr; gap: 20px; padding: 24px 0; } } .scan-hero .ed-display { margin: 20px 0 0; } .scan-hero-meta { font-family: var(--f-sans); font-size: 13px; line-height: 1.65; color: var(--ink-2); max-width: 38ch; margin: 0; } .scan-hero-meta b { font-weight: 500; color: var(--ink); } .scan-canvas { margin-top: 32px; border: 1px solid var(--ink); aspect-ratio: 3 / 2; background: var(--ink); position: relative; cursor: pointer; overflow: hidden; display: block; } .scan-canvas input[type="file"] { display: none; } .scan-canvas .frame { position: absolute; top: 22%; left: 14%; right: 14%; bottom: 26%; border: 1px dashed rgba(255,255,255,0.5); display: grid; place-items: center; color: rgba(255,255,255,0.85); font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; } .scan-canvas .chip-top { position: absolute; top: 16px; left: 16px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255,255,255,0.85); padding: 3px 8px; border: 1px solid rgba(255,255,255,0.5); } .scan-canvas .chip-top.right { left: auto; right: 16px; } .scan-canvas .bottom-bar { position: absolute; bottom: 20px; left: 0; right: 0; display: flex; justify-content: center; align-items: center; gap: 24px; } .scan-canvas .shoot { width: 64px; height: 64px; border: 3px solid var(--card); background: var(--card); cursor: pointer; box-shadow: 0 0 0 2px rgba(0,0,0,0.1); } .scan-canvas .preview-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: none; } .scan-canvas.is-filled .preview-img { display: block; } .scan-canvas.is-filled .frame, .scan-canvas.is-filled .shoot, .scan-canvas.is-filled .chip-top { display: none; } .scan-tools { display: flex; gap: 2px; flex-wrap: wrap; margin-top: 16px; align-items: center; } .scan-tools .sep { width: 1px; height: 12px; background: var(--line); margin: 0 10px; } .scan-tool { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); background: transparent; border: 0; padding: 6px 8px; cursor: pointer; text-decoration: none; } .scan-tool:hover { color: var(--ink); } .scan-selected { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; color: var(--ink-3); text-align: right; min-height: 12px; margin-top: 8px; } .scan-status { padding: 12px 16px; border: 1px solid; font-family: var(--f-sans); font-size: 13px; margin-top: 10px; } .scan-status.error { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); } .scan-status.ok { border-color: var(--ok); color: var(--ok); background: var(--ok-soft); } .scan-cta-row { display: grid; grid-template-columns: 1fr auto; gap: 20px; align-items: end; margin-top: 16px; padding-top: 20px; border-top: 1px solid var(--line); } .scan-cta-row .meta { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); line-height: 1.6; } .scan-cta-row .meta b { color: var(--ink); } /* === Result view (variant B — Score-first with editorial twist) === */ .result-view { padding: 32px 0 24px; } .result-back { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); background: transparent; border: 0; padding: 0; cursor: pointer; margin-bottom: 24px; } .result-back:hover { color: var(--ink); } .result-score-block { display: grid; grid-template-columns: 1.1fr 1fr; gap: 40px; align-items: end; padding: 40px 0; border-bottom: 1px solid var(--line); } .result-score-number { font-family: var(--f-serif); font-size: clamp(90px, 18vw, 180px); line-height: 0.9; letter-spacing: -0.04em; color: var(--ink); font-weight: 400; } body.result-ok .result-score-number { color: var(--ok); } body.result-warn .result-score-number { color: var(--warn); } body.result-bad .result-score-number { color: var(--bad); } .result-score-verdict { font-family: var(--f-serif); font-style: italic; font-size: 24px; line-height: 1; color: var(--ink-2); margin: 4px 0 8px; } .result-score-sub { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); line-height: 1.7; } .result-score-sub b { color: var(--ink); font-weight: 400; } @media (max-width: 640px) { .result-score-block { grid-template-columns: 1fr; gap: 12px; align-items: start; } } .result-product { display: grid; grid-template-columns: 56px 1fr auto; gap: 16px; align-items: center; padding: 18px 0; border-bottom: 1px solid var(--line); } .result-product img { width: 56px; height: 56px; object-fit: contain; background: var(--paper-2); } .result-product .pc-brand { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px; } .result-product .pc-name { font-family: var(--f-serif); font-size: 18px; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; } .result-metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; padding: 18px 0; border-bottom: 1px solid var(--line); } .result-metrics .metric { padding: 0 12px 0 0; border-right: 1px solid var(--line); display: flex; flex-direction: column; gap: 2px; } .result-metrics .metric:last-child { border-right: 0; } .result-metrics .metric strong { font-family: var(--f-serif); font-size: 38px; line-height: 1; font-weight: 400; letter-spacing: -0.02em; color: var(--ink); } .result-metrics .metric.metric-low strong { color: var(--ok); } .result-metrics .metric.metric-medium strong { color: var(--warn); } .result-metrics .metric.metric-high strong { color: var(--bad); } .result-metrics .metric span { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); } @media (max-width: 480px) { .result-metrics { grid-template-columns: 1fr 1fr; gap: 12px; } .result-metrics .metric { border-right: 0; border-bottom: 1px solid var(--line); padding-bottom: 8px; } .result-metrics .metric:nth-last-child(-n+2) { border-bottom: 0; } } .result-block { padding: 22px 0; border-bottom: 1px solid var(--line); } .result-block h3 { font-family: var(--f-mono); font-size: 10px; font-weight: 400; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 12px; } /* Ingredients table — newspaper-style */ .data-table { width: 100%; border-collapse: collapse; font-family: var(--f-sans); font-size: 13px; } .data-table th { text-align: left; font-family: var(--f-mono); font-size: 9px; font-weight: 400; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); padding: 10px 0; border-top: 1px solid var(--ink); border-bottom: 1px solid var(--line); } .data-table td { padding: 10px 0; border-bottom: 1px solid var(--line); vertical-align: top; font-family: var(--f-sans); font-size: 13px; color: var(--ink-2); } .data-table td:nth-child(2) { text-align: right; white-space: nowrap; } .ing-badge { display: inline-block; padding: 2px 8px; font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; background: var(--paper-2); color: var(--ink-2); border: 1px solid var(--line); } .ing-badge.low { background: var(--ok-soft); color: var(--ok); border-color: #b9ccab; } .ing-badge.medium { background: var(--warn-soft); color: var(--warn); border-color: #d6c28a; } .ing-badge.high { background: var(--bad-soft); color: var(--bad); border-color: #d6aca7; } .ing-badge.unknown { background: var(--paper-2); color: var(--ink-3); border-color: var(--line); } .ing-note-link { color: var(--accent); text-decoration: underline; cursor: pointer; font-family: var(--f-mono); font-size: 9px; margin-left: 6px; } .result-cta-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 20px 0 0; } .result-inline-actions { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; } .result-inline-actions .scan-tool { padding: 0; } .result-sources { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); margin-top: 32px; padding-top: 14px; border-top: 1px solid var(--line); text-align: left; line-height: 1.7; } .admin-toggle { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-4); background: transparent; border: 0; padding: 6px 0; cursor: pointer; margin-top: 20px; } .admin-toggle:hover { color: var(--ink-2); } /* === Overlay base === */ .overlay { position: fixed; inset: 0; background: rgba(15, 15, 14, 0.7); z-index: 60; display: none; padding: 28px; overflow-y: auto; align-items: center; justify-content: center; } .overlay.is-open { display: flex; } .overlay .panel { background: var(--card); border: 1px solid var(--ink); max-width: 520px; width: 100%; padding: 32px; max-height: 92vh; overflow-y: auto; } .overlay .panel-head { display: flex; justify-content: space-between; align-items: flex-start; padding-bottom: 18px; border-bottom: 1px solid var(--line); margin-bottom: 18px; } .overlay .panel-head h2 { font-family: var(--f-serif); font-size: 32px; line-height: 1; font-weight: 400; letter-spacing: -0.02em; margin: 0; } .overlay .panel-head h2 em { font-style: italic; color: var(--accent); } .overlay .panel-head .close { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); background: transparent; border: 0; cursor: pointer; } /* === Ambiguous v2 candidate cards === */ .cand-card { display: grid; grid-template-columns: 72px 1fr; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--line); cursor: pointer; transition: opacity .12s; align-items: center; } .cand-card:hover { opacity: 0.75; } .cand-card.selected { padding: 16px; background: var(--accent-soft); border: 1px solid var(--accent); margin: 0 -16px; } .cand-card .cc-photo { width: 72px; height: 72px; background-size: cover; background-position: center; background-color: var(--paper-2); border: 1px solid var(--line); } .cand-card .cc-brand { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px; } .cand-card .cc-name { font-family: var(--f-serif); font-size: 18px; font-weight: 400; line-height: 1.15; letter-spacing: -0.01em; } .cand-card .cc-match { display: flex; align-items: center; gap: 10px; margin-top: 6px; } .cand-card .cc-match .bar { flex: 1; height: 2px; background: var(--line); position: relative; overflow: hidden; } .cand-card .cc-match .bar i { display: block; position: absolute; left: 0; top: 0; bottom: 0; background: var(--accent); } .cand-card .cc-pct { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.08em; color: var(--ink); font-weight: 500; } /* === Loading stages === */ .loading-title { font-family: var(--f-serif); font-size: 28px; line-height: 1; font-weight: 400; letter-spacing: -0.02em; margin: 0 0 6px; } .loading-title em { font-style: italic; color: var(--accent); } .loading-sub { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 20px; } .loading-stage { display: grid; grid-template-columns: 32px 1fr auto; gap: 14px; padding: 10px 0; border-bottom: 1px solid var(--line); align-items: center; } .loading-stage .num { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; color: var(--ink-3); } .loading-stage.done .num { color: var(--accent); } .loading-stage.doing .num { color: var(--accent); animation: l-pulse 1.4s infinite; } .loading-stage .label { font-family: var(--f-sans); font-size: 14px; color: var(--ink); } .loading-stage.wait .label { color: var(--ink-4); } .loading-stage .ms { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.08em; color: var(--ink-3); } .loading-stage.done .ms { color: var(--ok); } @keyframes l-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } } .loading-tip { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line); font-family: var(--f-sans); font-size: 12px; color: var(--ink-3); font-style: italic; line-height: 1.65; } .loading-tip::before { content: "— "; color: var(--accent); font-style: normal; } /* === Onboarding === */ .onboard-content { text-align: center; padding: 24px 8px 12px; } .onboard-num { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.2em; color: var(--accent); } .onboard-title { font-family: var(--f-serif); font-size: clamp(40px, 8vw, 72px); line-height: 0.95; font-weight: 400; letter-spacing: -0.025em; margin: 10px auto 12px; max-width: 14ch; } .onboard-title em { font-style: italic; color: var(--accent); } .onboard-sub { font-family: var(--f-serif); font-style: italic; font-size: 16px; color: var(--ink-2); line-height: 1.4; max-width: 32ch; margin: 0 auto; } .onboard-dots { display: flex; justify-content: center; gap: 4px; margin: 28px 0 20px; } .onboard-dots span { width: 8px; height: 1px; background: var(--line-2); } .onboard-dots span.on { background: var(--accent); height: 2px; } .onboard-foot { display: flex; justify-content: space-between; align-items: center; } /* === Share bottom sheet === */ .share-sheet { position: fixed; left: 0; right: 0; bottom: 0; background: var(--card); border-top: 1px solid var(--ink); padding: 24px 28px 32px; z-index: 70; transform: translateY(100%); transition: transform .3s; max-width: 600px; margin: 0 auto; } .share-sheet.is-open { transform: translateY(0); } .share-backdrop { position: fixed; inset: 0; background: rgba(15,15,14,0.55); z-index: 69; opacity: 0; pointer-events: none; transition: opacity .3s; } .share-backdrop.is-open { opacity: 1; pointer-events: auto; } .share-sheet h3 { font-family: var(--f-serif); font-size: 24px; font-weight: 400; letter-spacing: -0.02em; margin: 0 0 18px; line-height: 1; } .share-preview { display: grid; grid-template-columns: 48px 1fr; gap: 14px; padding: 12px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); align-items: center; } .share-preview img { width: 48px; height: 48px; object-fit: contain; background: var(--paper-2); } .share-preview .sp-brand { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; color: var(--ink-3); text-transform: uppercase; } .share-preview .sp-name { font-family: var(--f-serif); font-size: 16px; line-height: 1.15; } .share-link-row { display: flex; gap: 0; align-items: center; margin-top: 18px; border: 1px solid var(--line); } .share-link-row input { flex: 1; padding: 10px 12px; border: 0; font-family: var(--f-mono); font-size: 11px; color: var(--ink-2); background: transparent; } .share-link-row button { padding: 10px 16px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; background: var(--ink); color: var(--card); border: 0; cursor: pointer; } .share-icons { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; margin-top: 18px; background: var(--line); border: 1px solid var(--line); } .share-icons a { background: var(--card); padding: 16px 8px; text-align: center; color: var(--ink); text-decoration: none; transition: background .12s; } .share-icons a:hover { background: var(--paper-2); } .share-icons .si-mark { font-family: var(--f-serif); font-size: 22px; line-height: 1; font-style: italic; color: var(--accent); } .share-icons .si-label { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; margin-top: 6px; } /* === Flag === */ .flag-form { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); } .flag-form h4 { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); font-weight: 400; margin: 0 0 10px; } .flag-form .opt { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; font-family: var(--f-sans); font-size: 13px; border-bottom: 1px solid var(--line); cursor: pointer; color: var(--ink-2); } .flag-form .opt:hover { color: var(--ink); } .flag-form .opt.on { color: var(--ink); } .flag-form .opt .rad { width: 14px; height: 14px; border: 1px solid var(--ink-3); position: relative; } .flag-form .opt.on .rad { border-color: var(--accent); } .flag-form .opt.on .rad::after { content: ""; position: absolute; inset: 3px; background: var(--accent); } .flag-form textarea { width: 100%; min-height: 64px; border: 1px solid var(--line); padding: 10px 12px; font-family: var(--f-sans); font-size: 13px; background: var(--card); margin-top: 14px; resize: vertical; line-height: 1.5; } .flag-form textarea:focus { outline: none; border-color: var(--ink); } .flag-thanks { text-align: center; padding: 40px 0 20px; } .flag-thanks .title { font-family: var(--f-serif); font-size: 72px; line-height: 1; font-weight: 400; letter-spacing: -0.03em; color: var(--accent); } .flag-thanks em { font-style: italic; } .flag-thanks .q { font-family: var(--f-serif); font-style: italic; font-size: 16px; color: var(--ink-2); margin: 10px 0 0; line-height: 1.5; } .flag-thanks .idchip { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; color: var(--ink-3); margin-top: 16px; display: inline-block; padding: 4px 8px; border: 1px solid var(--line); } /* === Admin drawer === */ .admin-backdrop { position: fixed; inset: 0; background: rgba(15,15,14,0.55); z-index: 60; } .admin-panel { position: fixed; top: 0; right: 0; width: min(100vw, 420px); height: 100vh; background: var(--card); border-left: 1px solid var(--ink); z-index: 70; display: flex; flex-direction: column; } .admin-head { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid var(--ink); } .admin-head h3 { font-family: var(--f-serif); font-size: 22px; font-weight: 400; margin: 0; } .admin-head h3 em { font-style: italic; color: var(--accent); } .admin-close { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; background: transparent; border: 0; cursor: pointer; color: var(--ink-3); } .admin-content { flex: 1; overflow-y: auto; padding: 20px 24px; } .admin-block { margin-bottom: 24px; } .admin-block h4 { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 10px; font-weight: 400; } .admin-field label { display: block; font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; color: var(--ink-3); margin-bottom: 4px; text-transform: uppercase; } .admin-field input { width: 100%; padding: 8px 10px; font-family: var(--f-mono); font-size: 11px; border: 1px solid var(--line); background: var(--card); color: var(--ink); } .admin-metric { display: flex; justify-content: space-between; padding: 8px 0; font-family: var(--f-sans); font-size: 12px; border-bottom: 1px solid var(--line); color: var(--ink-3); } .admin-metric code { font-family: var(--f-mono); font-size: 11px; color: var(--ink); background: transparent; } .chips { display: flex; gap: 4px; flex-wrap: wrap; } .accordions .accordion-item { border-top: 1px solid var(--line); } .accordion-header { padding: 10px 0; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); cursor: pointer; } .accordion-body { padding: 0 0 10px; font-family: var(--f-mono); font-size: 10px; color: var(--ink-2); display: none; } .accordion-item.open .accordion-body { display: block; } .admin-log, #rawJson { font-family: var(--f-mono); font-size: 10px; color: var(--ink-2); margin: 0; padding: 10px; background: var(--paper-2); border: 1px solid var(--line); overflow: auto; max-height: 240px; white-space: pre-wrap; word-break: break-word; } .admin-network-list { display: flex; flex-direction: column; gap: 4px; } .admin-network-item { padding: 8px 10px; background: var(--paper-2); border: 1px solid var(--line); font-family: var(--f-mono); font-size: 10px; color: var(--ink-2); word-break: break-word; } /* === Modal (note) === */ .modal { position: fixed; inset: 0; background: rgba(15,15,14,0.7); z-index: 50; display: flex; align-items: center; justify-content: center; padding: 28px; } .modal-card { background: var(--card); border: 1px solid var(--ink); max-width: 560px; width: 100%; max-height: 88vh; overflow-y: auto; } .modal-head { display: flex; justify-content: space-between; align-items: center; padding: 18px 24px; border-bottom: 1px solid var(--line); } .modal-head h3 { font-family: var(--f-serif); font-size: 22px; font-weight: 400; margin: 0; } .modal-close { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; background: transparent; border: 0; cursor: pointer; color: var(--ink-3); } .modal-text { padding: 20px 24px; font-family: var(--f-sans); font-size: 14px; line-height: 1.7; color: var(--ink-2); } /* === History drawer (pinned under nav) === */ .history-menu { position: relative; } .history-panel { position: absolute; top: calc(100% + 10px); right: 0; background: var(--card); border: 1px solid var(--ink); padding: 16px; width: 340px; max-height: 70vh; overflow-y: auto; z-index: 40; } .history-panel-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; } .history-panel-head .text-label { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.16em; color: var(--ink-3); text-transform: uppercase; } .history-close { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; background: transparent; border: 0; color: var(--ink-3); cursor: pointer; } .recent-list { display: flex; flex-direction: column; gap: 0; } .recent-item { display: grid; grid-template-columns: 40px 1fr auto; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); align-items: center; cursor: pointer; } .recent-item:hover { background: var(--paper-2); } .recent-item img { width: 40px; height: 40px; object-fit: contain; background: var(--paper-2); } .recent-item .rec-name { font-family: var(--f-serif); font-size: 14px; line-height: 1.15; } .recent-item .rec-meta { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.1em; color: var(--ink-3); margin-top: 2px; } .empty-recent { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; color: var(--ink-3); text-align: center; padding: 20px; } /* === Prod footer === */ .prod-footer { border-top: 1px solid var(--line); margin-top: 80px; padding: 36px 32px 48px; } .prod-footer__inner { max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: auto 1fr; gap: 32px; align-items: flex-start; } .prod-footer img { width: 72px; height: auto; } .prod-footer p { font-family: var(--f-sans); font-size: 11px; color: var(--ink-3); margin: 0 0 6px; line-height: 1.7; max-width: 68ch; } .prod-footer p.f-company { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.1em; color: var(--ink-4); } .prod-footer a { color: var(--ink-2); text-decoration: underline; } @media (max-width: 640px) { .prod-footer__inner { grid-template-columns: 1fr; } } /* === Hide wireframe-explorer chrome on production pages === */ .tweaks, .tweaks-fab, .screen-intro, .shell-head, .tabbar, .vars, .notes, .phone, .phone-screen, .phone-status { display: none !important; } .screen { display: block !important; } /* === Ingredient group card (product-details variant B) === */ .ing-group { padding: 22px 0; border-bottom: 1px solid var(--line); } .ing-group:first-of-type { border-top: 1px solid var(--ink); } .ing-group h4 { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); margin: 0 0 10px; font-weight: 400; } /* === Compare store rows (variant A) === */ .store-row { display: grid; grid-template-columns: 1fr auto; padding: 20px 0; border-bottom: 1px solid var(--line); align-items: baseline; gap: 20px; } .store-row.winner { border-bottom: 2px solid var(--accent); padding: 24px 0; } .store-row.out { opacity: 0.4; } .store-row .name { font-family: var(--f-serif); font-size: 22px; font-weight: 400; letter-spacing: -0.01em; } .store-row.winner .name em { font-style: italic; color: var(--accent); } .store-row .price { font-family: var(--f-serif); font-size: 28px; font-weight: 400; letter-spacing: -0.02em; line-height: 1; } .store-row.winner .price { font-size: 44px; color: var(--accent); } .store-row.out .price { font-family: var(--f-mono); font-size: 13px; color: var(--ink-3); letter-spacing: 0.12em; text-transform: uppercase; } .store-row .delivery { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; color: var(--ink-3); text-transform: uppercase; margin-top: 4px; text-align: right; } /* ===== SPA shell — Vivino-style routes ===== */ .spa-app { max-width: 720px; margin: 0 auto; min-height: 100vh; background: var(--paper); display: flex; flex-direction: column; } .spa-app[data-debug="1"] .spa-debug { display: block; } .spa-screen { display: none; flex: 1 1 auto; flex-direction: column; padding: 16px 20px 96px; } .spa-screen.on { display: flex; } .spa-screen-back { display: inline-flex; align-items: center; gap: 6px; font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.1em; color: var(--ink-3); text-transform: uppercase; background: transparent; border: 0; padding: 4px 0; cursor: pointer; margin-bottom: 16px; text-decoration: none; } .spa-screen-back:hover { color: var(--ink); } .spa-share { margin-left: auto; font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.1em; color: var(--ink-3); background: transparent; border: 0; cursor: pointer; text-transform: uppercase; } .spa-screen-head { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; } .viewfinder { position: relative; background: #0f0f0e; border: 1px solid var(--line); border-radius: 2px; aspect-ratio: 3/4; width: 100%; overflow: hidden; display: grid; place-items: center; margin: 8px 0 24px; } .viewfinder video { width: 100%; height: 100%; object-fit: contain; display: block; } .viewfinder.camera-off video { opacity: 0.18; } .viewfinder.camera-idle video { opacity: 0; } .viewfinder canvas { display: none; } .viewfinder-hint { position: absolute; inset: 0; display: grid; place-items: center; color: rgba(255,255,255,0.55); font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; text-align: center; pointer-events: none; } .viewfinder.has-batch .viewfinder-hint { align-items: start; padding-top: 22px; color: rgba(255,255,255,0.68); } .viewfinder-corner { position: absolute; width: 28px; height: 28px; border: 2px solid rgba(255,255,255,0.9); pointer-events: none; } .viewfinder-corner.tl { top: 16px; left: 16px; border-right: 0; border-bottom: 0; } .viewfinder-corner.tr { top: 16px; right: 16px; border-left: 0; border-bottom: 0; } .viewfinder-corner.bl { bottom: 16px; left: 16px; border-right: 0; border-top: 0; } .viewfinder-corner.br { bottom: 16px; right: 16px; border-left: 0; border-top: 0; } .scan-entry-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 0 0 10px; } .scan-entry-actions .w-btn { min-width: 0; min-height: 44px; display: grid; place-items: center; padding: 9px 8px; line-height: 1.18; text-decoration: none; cursor: pointer; overflow-wrap: anywhere; } .shutter-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: center; padding: 8px 0 24px; } .shutter-btn { width: 84px; height: 84px; border-radius: 50%; border: 3px solid var(--ink); background: var(--card); cursor: pointer; padding: 0; display: grid; place-items: center; grid-column: 2; position: relative; } .shutter-btn::after { content: ""; width: 64px; height: 64px; border-radius: 50%; background: var(--ink); transition: transform .12s; } .shutter-btn:active::after { transform: scale(0.9); } .shutter-btn:disabled { opacity: 0.4; cursor: wait; } .shutter-row.camera-off { grid-template-columns: 1fr; justify-items: center; } .shutter-row.camera-off .shutter-btn, .shutter-row.camera-off .shutter-caption { display: none; } .shutter-row.camera-off .aux-btn.left { grid-column: 1; } .aux-btn { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); background: transparent; border: 0; padding: 8px; cursor: pointer; text-align: center; } .aux-btn:hover { color: var(--ink); } .aux-btn.left { justify-self: end; } .aux-btn.right { justify-self: start; } .scan-batch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 4; padding: 12px; border: 1px solid rgba(255,255,255,0.32); background: rgba(15,15,14,0.74); color: #fff; backdrop-filter: blur(10px); } .scan-batch[hidden] { display: none; } .scan-batch-head { display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; margin-bottom: 8px; } .scan-batch .kicker { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.58); } .scan-batch .title { font-family: var(--f-serif); font-size: 18px; line-height: 1; letter-spacing: -0.02em; margin-top: 3px; } .scan-batch .aux-btn { color: rgba(255,255,255,0.72); padding: 0; } .scan-thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 8px 0 10px; } .scan-thumb { position: relative; aspect-ratio: 4 / 3; background: var(--paper-2); border: 1px solid rgba(255,255,255,0.28); overflow: hidden; } .scan-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; } .scan-thumb span { position: absolute; left: 6px; top: 6px; min-width: 18px; height: 18px; display: grid; place-items: center; background: var(--ink); color: var(--card); font-family: var(--f-mono); font-size: 10px; } .scan-thumb button { position: absolute; right: 4px; top: 4px; width: 44px; height: 44px; border: 0; background: rgba(255,255,255,0.88); color: var(--ink); cursor: pointer; font-size: 18px; line-height: 1; } .scan-thumb button.rotate { right: 52px; font-size: 18px; } .scan-thumb button.remove { right: 4px; } .scan-batch-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .scan-batch-actions .w-btn { min-height: 44px; padding: 0 10px; font-size: 10px; } .scan-batch-actions .w-btn:not(.primary) { color: #fff; border-color: rgba(255,255,255,0.44); background: rgba(255,255,255,0.08); } @media (max-width: 480px) { .scan-batch { left: 8px; right: 8px; bottom: 8px; } .scan-batch-actions { grid-template-columns: 1fr; } } .spa-tabbar { position: sticky; bottom: 0; z-index: 10; background: var(--card); border-top: 1px solid var(--line); display: grid; grid-template-columns: repeat(3, 1fr); padding: 8px 0 calc(8px + env(safe-area-inset-bottom)); } .spa-tabbar[hidden] { display: none; } .spa-tabbar a { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-4); text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 4px 8px; } .spa-tabbar a.on { color: var(--ink); } .spa-tabbar a span:first-child { font-family: var(--f-sans); font-size: 16px; line-height: 1; } .spa-loading { position: fixed; inset: 0; background: rgba(255,255,255,0.92); display: none; place-items: center; z-index: 100; backdrop-filter: blur(4px); } .spa-loading.on { display: grid; } .spa-loading-inner { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-2); animation: spa-pulse 1.4s ease-in-out infinite; } @keyframes spa-pulse { 0%,100%{opacity:1} 50%{opacity:0.4} } .spa-product-hero { display: grid; gap: 4px; padding: 8px 0 20px; } .spa-product-hero .img { width: 100%; max-width: 360px; min-height: 220px; margin: 0 auto 16px; background: var(--paper-2); border: 1px solid var(--line); display: grid; place-items: center; overflow: visible; } .candidate-loading { padding: 36px 0; text-align: center; } .spa-product-hero .img img { width: auto; height: auto; max-width: 100%; max-height: 520px; object-fit: contain; } .spa-product-hero .brand { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); } .spa-product-hero .name { font-family: var(--f-serif); font-size: 28px; font-weight: 400; line-height: 1.1; letter-spacing: -0.02em; margin: 4px 0; } .spa-title-score-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: center; margin: 4px 0 8px; } .spa-title-score-row.ingredient { grid-template-columns: auto minmax(0, 1fr); justify-content: start; align-items: center; margin: 0 0 10px; } .spa-title-score-row .w-h { margin: 0; } .spa-title-score-row .w-score { justify-self: end; flex: 0 0 auto; } .spa-title-score-row.ingredient .w-score { justify-self: start; } .spa-product-hero .meta { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.05em; color: var(--ink-3); } .spa-index-card { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: center; padding: 16px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin-bottom: 24px; } .spa-index-card .label { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 4px; } .spa-index-card .stripe { height: 2px; background: var(--line); margin-top: 6px; } .spa-index-card .stripe i { display: block; height: 100%; background: var(--ok); } .spa-index-card .stripe i.warn { background: var(--warn); } .spa-index-card .stripe i.bad { background: var(--bad); } .spa-index-card .desc { font-size: 12.5px; color: var(--ink-2); margin-top: 6px; line-height: 1.5; } .spa-score-reasons { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--line-2); background: var(--paper-2); } .spa-score-reasons .reason-title { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; } .spa-score-reasons ul { margin: 0; padding-left: 16px; color: var(--ink-2); font-size: 12.5px; line-height: 1.45; } .spa-score-reasons li + li { margin-top: 3px; } .spa-data-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; } .spa-data-pills span { border: 1px solid var(--line-2); background: var(--paper-2); color: var(--ink-2); border-radius: 999px; padding: 4px 8px; font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; } .spa-section-head { font-family: var(--f-mono); font-size: 10px; font-weight: 400; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); margin: 24px 0 8px; display: flex; align-items: baseline; gap: 8px; } .spa-section-head .count { font-family: var(--f-mono); font-size: 10px; color: var(--ink-4); } .spa-ing { display: grid; grid-template-columns: 14px 1fr auto auto; gap: 12px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); cursor: pointer; user-select: auto; color: var(--ink); text-decoration: none; } .spa-ing .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); justify-self: center; } .spa-ing .dot.warn { background: var(--warn); } .spa-ing .dot.bad { background: var(--bad); } .spa-ing .dot.neutral { background: var(--ink-4); } .spa-ing .unknown-mark { width: 16px; height: 16px; border-radius: 50%; display: inline-grid; place-items: center; justify-self: center; background: var(--bad-soft); color: var(--bad); border: 1px solid #d5b4ae; font-family: var(--f-mono); font-size: 11px; font-weight: 700; line-height: 1; } .spa-ing .n { font-size: 13px; line-height: 1.3; } .spa-ing .m { font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); margin-top: 2px; letter-spacing: 0.04em; } .spa-ing .r { font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); letter-spacing: 0.04em; text-align: right; } .spa-ing .toggle { color: var(--ink-4); font-family: var(--f-mono); font-size: 12px; } .spa-price-row { display: grid; grid-template-columns: 1fr auto auto; gap: 12px; align-items: baseline; min-height: 44px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 13px; color: var(--ink); text-decoration: none; } .spa-price-row:last-child { border-bottom: 0; } .spa-price-row .store { color: var(--ink); } .spa-price-row .price { font-family: var(--f-serif); font-size: 17px; } .spa-price-row .arrow { color: var(--ink-3); } .spa-price-row a { color: inherit; text-decoration: none; } .spa-cand { display: grid; grid-template-columns: 64px 1fr auto auto; gap: 14px; align-items: center; padding: 14px 12px; border: 1px solid var(--line); border-radius: 2px; background: var(--card); margin-bottom: 10px; text-decoration: none; color: var(--ink); cursor: pointer; } .spa-cand:hover { border-color: var(--ink); } .spa-cand .img { width: 64px; height: 64px; background: var(--paper-2); border: 1px solid var(--line); display: grid; place-items: center; overflow: hidden; } .spa-cand .img img { width: 100%; height: 100%; object-fit: contain; } .spa-cand .brand { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); } .spa-cand .name { font-size: 13px; line-height: 1.35; margin-top: 2px; } .spa-cand.large { display: grid; grid-template-columns: 112px 1fr; gap: 14px; align-items: center; min-height: 136px; padding: 12px; overflow: hidden; } .spa-cand.large .img { width: 112px; height: 112px; min-height: 112px; border: 1px solid var(--line); } .spa-cand.large .img span { font-family: var(--f-mono); font-size: 10px; color: var(--ink-4); letter-spacing: 0.12em; text-transform: uppercase; } .spa-cand.large .content { padding: 0; display: flex; flex-direction: column; justify-content: center; min-width: 0; } .spa-cand.large .rank, .spa-cand.large .ref { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-4); } .spa-cand.large .ref { margin: 6px 0 12px; color: var(--ink-3); text-transform: none; letter-spacing: 0.04em; } .spa-cand.large .name { font-family: var(--f-serif); font-size: 19px; line-height: 1.14; letter-spacing: 0; margin: 0; } .spa-cand.large .desc { margin: 8px 0 0; font-size: 13px; line-height: 1.4; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; } .spa-cand.large .match-grid { display: grid; grid-template-columns: 86px 1fr; gap: 6px 10px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); } .spa-cand.large .match-grid span { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-4); } .spa-cand.large .match-grid strong { font-family: var(--f-sans); font-size: 12px; color: var(--ink-2); font-weight: 500; overflow-wrap: anywhere; } .spa-cand.large .open-card { display: inline-block; margin-top: 14px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink); border-bottom: 1px solid var(--ink); width: max-content; } @media (max-width: 560px) { .spa-cand.large { grid-template-columns: 84px 1fr; min-height: 108px; gap: 12px; } .spa-cand.large .img { width: 84px; height: 84px; min-height: 84px; } .spa-cand.large .name { font-size: 17px; } .spa-cand.large .desc { -webkit-line-clamp: 3; } } .spa-ocr-list { font-family: var(--f-mono); font-size: 11px; background: var(--paper-2); border: 1px solid var(--line); padding: 12px; margin: 12px 0 20px; color: var(--ink-2); } .spa-ocr-list span { display: block; padding: 2px 0; } .spa-ocr-list span::before { content: "\\00B7 "; color: var(--ink-4); } .spa-search { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: center; padding: 8px 0 16px; border-bottom: 1px solid var(--line); } .spa-search .icon { font-size: 16px; color: var(--ink-3); } .spa-search input { border: 0; outline: 0; background: transparent; font-family: var(--f-sans); font-size: 16px; width: 100%; color: var(--ink); } .spa-list-row { display: grid; grid-template-columns: 48px 1fr auto; gap: 12px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); text-decoration: none; color: var(--ink); cursor: pointer; } .spa-list-row:last-child { border-bottom: 0; } .spa-list-row .thumb { width: 48px; height: 48px; background: var(--paper-2); border: 1px solid var(--line); } .spa-list-row .thumb img { width: 100%; height: 100%; object-fit: contain; } .spa-list-row .brand { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); } .spa-list-row .name { font-size: 13px; line-height: 1.35; margin-top: 2px; } .spa-list-row .arrow { font-family: var(--f-mono); font-size: 11px; color: var(--ink-3); } .spa-ing .role { margin-top: 3px; font-size: 12px; line-height: 1.3; color: var(--ink-3); } .spa-list-section { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-4); padding: 16px 0 6px; } .spa-debug { display: none; margin: 32px 0 8px; padding: 12px; border: 1px dashed var(--ink-4); border-radius: 2px; font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); background: var(--paper-2); white-space: pre-wrap; word-break: break-word; max-height: 360px; overflow: auto; } .spa-debug h5 { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; margin: 8px 0 4px; color: var(--ink-2); } .spa-debug pre { margin: 0; font-size: 10px; } .spa-provenance { margin: -4px 0 18px; padding: 12px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); } .spa-provenance .meta-row { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.06em; color: var(--ink-3); line-height: 1.6; } .spa-provenance a { display: inline-block; margin-top: 6px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--ink); max-width: 100%; overflow-wrap: anywhere; } .spa-debug-fab { display: none; position: fixed; right: 18px; bottom: 82px; z-index: 80; border: 1px solid var(--ink); background: var(--card); color: var(--ink); padding: 8px 10px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer; } .spa-app[data-debug="1"] .spa-debug-fab { display: block; } .spa-admin-drawer { position: fixed; top: 0; right: 0; width: min(100vw, 460px); height: 100vh; z-index: 90; background: var(--card); border-left: 1px solid var(--ink); transform: translateX(104%); transition: transform .22s ease; display: flex; flex-direction: column; box-shadow: -20px 0 40px rgba(15, 15, 14, 0.14); } .spa-app[data-debug="1"] .spa-admin-drawer.open { transform: translateX(0); } .spa-admin-head { display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; padding: 20px 22px 18px; border-bottom: 1px solid var(--ink); } .spa-admin-head .kicker, .spa-admin-body h3, .spa-admin-body h4 { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-3); font-weight: 400; margin: 0 0 8px; } .spa-admin-head h2 { font-family: var(--f-serif); font-size: 28px; line-height: 1; font-weight: 400; margin: 0; } .spa-admin-close { border: 0; background: transparent; color: var(--ink-3); cursor: pointer; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; } .spa-admin-body { overflow-y: auto; padding: 18px 22px 28px; } .spa-admin-body section { padding: 0 0 22px; margin: 0 0 22px; border-bottom: 1px solid var(--line); } .spa-admin-grid { margin: 8px 0 12px; } .spa-footer { font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.08em; color: var(--ink-4); padding: 24px 20px 16px; border-top: 1px solid var(--line); text-align: center; } .spa-footer a { color: var(--ink-3); text-decoration: none; border-bottom: 1px solid var(--line-2); } .spa-footer img { height: 18px; vertical-align: middle; margin-right: 8px; opacity: 0.7; } /* ===== Mobile app hardening ===== The SPA must behave like an installed app on phones: no horizontal pan, no footer-driven dead scroll on the scanner, and a tabbar pinned to the visual viewport rather than participating in page flow. */ html { width: 100%; max-width: 100%; overflow-x: hidden; overscroll-behavior-x: none; -webkit-text-size-adjust: 100%; } body { width: 100%; max-width: 100%; min-width: 0; min-height: 100svh; overflow-x: hidden; overflow-x: clip; overscroll-behavior-x: none; touch-action: pan-y pinch-zoom; } body:has(.spa-app) { min-height: 100svh; background: var(--paper); } .spa-app { width: 100%; max-width: 720px; min-width: 0; min-height: 100svh; overflow-x: hidden; overflow-x: clip; isolation: isolate; } .spa-app *, .spa-app *::before, .spa-app *::after { max-width: 100%; } .spa-screen { width: 100%; min-width: 0; overflow-x: hidden; overflow-x: clip; padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); padding-bottom: calc(92px + env(safe-area-inset-bottom)); } .spa-screen[data-route="scan"] { min-height: 100svh; padding-top: max(12px, env(safe-area-inset-top)); padding-bottom: calc(112px + env(safe-area-inset-bottom)); } .spa-screen[data-route="scan"].on { justify-content: space-between; } .spa-screen[data-route="scan"] .viewfinder { margin-top: 0; margin-bottom: 12px; max-height: calc(100svh - 410px - env(safe-area-inset-bottom)); } .spa-screen[data-route="scan"] .shutter-row { padding-bottom: 0; } .spa-tabbar { position: fixed; left: 50%; right: auto; bottom: 0; width: min(720px, 100vw); max-width: 100vw; transform: translateX(-50%); z-index: 70; box-shadow: 0 -12px 28px rgba(15, 15, 14, 0.06); } .spa-footer { display: none; } .spa-footer.on { display: block; } .spa-footer a { display: inline-flex; align-items: center; min-height: 44px; } .spa-list-row, .spa-cand, .spa-ing, .spa-index-card, .spa-search, .scan-batch, .scan-batch-head, .scan-batch-actions { min-width: 0; } .spa-list-row > *, .spa-cand > *, .spa-ing > *, .spa-index-card > *, .scan-batch-head > * { min-width: 0; } .spa-list-row .name, .spa-cand .name, .spa-product-hero .name, .spa-ing .n, .spa-ing .m, .spa-provenance, .spa-data-pills, .w-txt { overflow-wrap: anywhere; } .spa-cand.large .open-card { width: fit-content; max-width: 100%; } .spa-admin-drawer, .spa-loading { max-width: 100vw; } @supports (height: 100dvh) { body:has(.spa-app), .spa-app, .spa-screen[data-route="scan"] { min-height: 100dvh; } .spa-screen[data-route="scan"] .viewfinder { max-height: max(180px, calc(100dvh - 410px - env(safe-area-inset-bottom))); } } .spa-score-method-link { justify-self: end; display: grid; justify-items: center; gap: 5px; color: var(--ink-3); text-decoration: none; font: 9px/1.2 var(--f-mono); letter-spacing: 0.04em; } .spa-score-method-link.ingredient { justify-self: start; } .spa-score-method-link:hover > span:last-child, .spa-score-method-link:focus-visible > span:last-child { color: var(--ink); text-decoration: underline; } .spa-price-row .store { display: grid; gap: 2px; } .spa-price-row .store small { color: var(--ink-3); font-size: 10px; font-weight: 400; } @media (orientation: landscape) and (max-height: 520px) { .spa-screen[data-route="scan"] .viewfinder { min-height: 180px; height: 46vh; max-height: 230px; aspect-ratio: auto; } } /* ===== V16 application repair ===== */ :root { --ink-4: #6f6f6b; } .sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; } .spa-skip-link { position: fixed; z-index: 200; top: 8px; left: 8px; transform: translateY(-160%); padding: 10px 14px; min-height: 44px; display: inline-flex; align-items: center; background: var(--ink); color: var(--paper); text-decoration: none; } .spa-skip-link:focus { transform: translateY(0); } .spa-app :focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; } .spa-app h1[tabindex="-1"]:focus { outline: none; } .spa-app { max-width: 820px; } .spa-screen-back, .spa-share, .spa-tabbar a, .aux-btn { min-height: 44px; } .spa-screen-back, .spa-share { padding: 10px 4px; margin-bottom: 0; } .spa-screen-head { min-height: 44px; } .scan-intro { padding: 2px 0 10px; } .scan-intro .w-h { font-size: 28px; margin-bottom: 4px; } .scan-intro .w-txt { color: var(--ink-3); margin: 0; } .scan-entry-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); } .shutter-row { position: relative; } .shutter-caption { grid-column: 2; grid-row: 2; justify-self: center; font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); } .scan-privacy-note { margin: 2px auto 8px; max-width: 560px; text-align: center; color: var(--ink-3); font-size: 11px; line-height: 1.45; } .scan-privacy-note a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; color: inherit; } .spa-tabbar { width: min(820px, 100vw); } .spa-tabbar a { font-size: 11px; justify-content: center; } .spa-loading { padding: 20px; } .spa-loading-card { width: min(380px, 100%); padding: 24px; border: 1px solid var(--line); background: var(--card); text-align: center; } .spa-loading-card p { margin: 10px 0 18px; color: var(--ink-3); } .spa-progress { height: 3px; background: var(--line); overflow: hidden; } .spa-progress i { display: block; width: 0; height: 100%; background: var(--ink); transition: width .25s ease; } .spa-loading-time { margin: 10px 0 16px; font-family: var(--f-mono); font-size: 11px; color: var(--ink-3); } .spa-toast { position: fixed; left: 50%; bottom: calc(78px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 160; width: min(420px, calc(100vw - 32px)); padding: 11px 14px; border: 1px solid var(--ink); background: var(--ink); color: var(--paper); text-align: center; font-size: 13px; } .spa-toast.bad { background: var(--bad); border-color: var(--bad); } .spa-toast.warn { background: var(--warn); border-color: var(--warn); color: var(--ink); } .search-controls { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--line); } .spa-search { border-bottom-color: var(--control-line); } .spa-search input { min-height: 44px; } .search-controls[hidden] { display: none; } .search-controls label { font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); text-transform: uppercase; } .search-controls select { display: block; width: 100%; min-height: 44px; margin-top: 5px; border: 1px solid var(--control-line); background: var(--card); color: var(--ink); padding: 6px 8px; } .search-empty, .spa-empty { padding: 28px 0; } .search-examples { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; } .search-examples button { border: 1px solid var(--control-line); background: var(--card); min-height: 44px; padding: 8px 10px; cursor: pointer; } .search-loading { padding: 26px 0; display: grid; gap: 8px; } .search-loading span, .ingredient-loading-lines span, .ingredient-page-skeleton span { display: block; height: 12px; background: linear-gradient(90deg, var(--paper-2), var(--line), var(--paper-2)); background-size: 200% 100%; animation: spa-shimmer 1.2s linear infinite; } .search-loading span:nth-child(2), .ingredient-loading-lines span:nth-child(2) { width: 78%; } .search-loading span:nth-child(3) { width: 56%; } .search-loading p, .ingredient-page-skeleton p { color: var(--ink-3); font-size: 12px; } @keyframes spa-shimmer { to { background-position: -200% 0; } } .search-summary { padding: 12px 0 4px; font-family: var(--f-mono); font-size: 11px; color: var(--ink-3); } .search-more { width: 100%; margin-top: 16px; } .search-row-tail { display: flex; align-items: center; gap: 8px; } .w-score.xs { width: 38px; height: 38px; font-size: 13px; } .spa-product-hero .img { min-height: 220px; padding: 12px; } .spa-product-hero .img img { max-height: 560px; object-fit: contain; } .spa-product-hero h1.name { letter-spacing: 0; } .product-gallery { display: flex; gap: 8px; overflow-x: auto; padding: 0 0 12px; } .product-gallery, .history-filters { touch-action: pan-x pinch-zoom; } .product-gallery button { flex: 0 0 56px; width: 56px; height: 56px; padding: 3px; border: 1px solid var(--control-line); background: var(--card); cursor: pointer; } .product-gallery button.on { border-color: var(--ink); } .product-gallery img { width: 100%; height: 100%; object-fit: contain; } .product-decision { margin: 14px 0 4px; padding: 14px 16px; border-left: 3px solid var(--ink); background: var(--paper-2); } .product-decision-lead { margin: 0; font-family: var(--f-serif); font-size: 18px; line-height: 1.35; } .product-decision ul { margin: 10px 0 0; padding-left: 18px; color: var(--ink-2); font-size: 13px; line-height: 1.45; } .product-positive-note { margin: 10px 0 0; color: var(--ink-2); font-size: 13px; } .product-description { margin-top: 20px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); } .product-description h2, .product-description summary { padding: 12px 0; margin: 0; cursor: pointer; font-family: var(--f-mono); font-size: 11px; font-weight: 400; text-transform: uppercase; } .product-description h2 { cursor: default; color: var(--ink-3); } .product-description p { margin: 0; padding: 0 0 14px; color: var(--ink-2); line-height: 1.55; } .ingredient-fast-shell { min-height: 82px; } .ingredient-loading-lines, .ingredient-page-skeleton { display: grid; gap: 10px; padding: 18px 0; } .ingredient-role-fallback { margin: 12px 0 20px; color: var(--ink-2); } .spa-title-actions { display: flex; justify-content: space-between; align-items: center; gap: 16px; } .history-note { margin: -10px 0 8px; } .history-no-score { font-family: var(--f-mono); font-size: 10px; color: var(--ink-3); } .history-search { width: 100%; min-height: 44px; margin: 6px 0 10px; padding: 0 12px; border: 1px solid var(--control-line); background: var(--card); color: var(--ink); font: 14px/1.2 var(--f-sans); } .history-filters { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; } .history-filters button { min-height: 44px; padding: 0 12px; border: 1px solid var(--control-line); background: var(--card); color: var(--ink-2); white-space: nowrap; cursor: pointer; font: 11px/1 var(--f-sans); } @media (max-width: 360px) { .history-filters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); overflow: visible; } .history-filters button { min-width: 0; padding-inline: 8px; } } .history-filters button.on { background: var(--ink); border-color: var(--ink); color: var(--paper); } .history-row { display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: stretch; border-bottom: 1px solid var(--line); } .history-row .spa-list-row { border-bottom: 0; min-width: 0; } .history-delete { width: 44px; min-height: 44px; align-self: center; border: 0; background: transparent; color: var(--ink-3); cursor: pointer; font: 20px/1 var(--f-sans); } .history-delete:hover, .history-delete:focus-visible { color: var(--ink); background: var(--paper-2); } .history-origin { margin-top: 4px; color: var(--ink-3); font: 10px/1.3 var(--f-mono); } .spa-ocr-list span::before { content: "· "; } .spa-admin-drawer[hidden] { display: none !important; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: 0.01ms !important; } } @media (max-width: 560px) { .scan-intro .w-h { font-size: 24px; } .scan-entry-actions { grid-template-columns: 1fr 1fr; } .scan-entry-actions .w-btn { font-size: 11px; } .shutter-row { grid-template-columns: minmax(88px, 1fr) auto minmax(88px, 1fr); } .shutter-caption { font-size: 9px; } .spa-product-hero .name { font-size: 24px; } .spa-title-score-row { align-items: start; } .spa-title-score-row .w-score { width: 62px; height: 62px; font-size: 28px; } .search-controls { grid-template-columns: 1fr; } .spa-list-row { min-height: 72px; } } @media (max-width: 480px) { .w-score.big { width: 72px; height: 72px; font-size: 32px; } .spa-title-score-row { gap: 12px; } .spa-screen { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); } .shutter-row { gap: 8px; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); } .aux-btn { font-size: 10px; letter-spacing: 0.06em; padding-left: 2px; padding-right: 2px; } .scan-entry-actions { gap: 6px; } .scan-entry-actions .w-btn { font-size: 11px; padding-left: 6px; padding-right: 6px; } } /* ===== V19 reference visual layer ===== The application keeps its routes and behavior; this layer carries the editorial typography, product scale and quiet surfaces from the landing. */ :root { --ink: #080a09; --ink-2: #303633; --ink-3: #68706b; --ink-4: #969d98; --line: #dde1de; --line-2: #c8cec9; --control-line: #aeb6b0; --paper: #fdfdfb; --paper-2: #f3f4f1; --paper-3: #e9ece8; --card: #ffffff; --accent: #147b29; --accent-soft: #e9f4e9; --ok: #147b29; --ok-soft: #e9f4e9; --warn: #ef7f12; --warn-soft: #fff0df; --bad: #a94942; --bad-soft: #f7e6e3; --f-serif: "Prata", Georgia, Cambria, serif; --f-sans: "Manrope", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --f-mono: "Manrope", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } html, body { background: #eef0ed; font-family: var(--f-sans); font-size: 15px; font-weight: 400; letter-spacing: 0; line-height: 1.55; } body:has(.spa-app) { background: #eef0ed; } .spa-app { width: 100%; max-width: 1040px; min-height: 100svh; border-inline: 1px solid rgba(174, 182, 176, .65); background: var(--paper); box-shadow: 0 0 54px rgba(20, 27, 22, .055); } .spa-brandbar { position: sticky; top: 0; z-index: 65; min-height: 72px; display: flex; align-items: center; justify-content: space-between; padding: 0 32px; border-bottom: 1px solid rgba(174, 182, 176, .72); background: rgba(253, 253, 251, .95); -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px); } .spa-brand { min-height: 48px; display: inline-flex; align-items: center; gap: 13px; color: var(--ink); font-family: var(--f-serif); font-size: 30px; line-height: 1; text-decoration: none; } .spa-brand-mark { position: relative; width: 32px; height: 32px; flex: 0 0 auto; display: inline-block; background: linear-gradient(var(--ink), var(--ink)) center / 3px 32px no-repeat, linear-gradient(var(--ink), var(--ink)) center / 32px 3px no-repeat; } .spa-brand-mark::before, .spa-brand-mark::after { content: ""; position: absolute; top: 0; left: 15px; width: 3px; height: 32px; border-radius: 3px; background: var(--ink); transform-origin: center; } .spa-brand-mark::before { transform: rotate(45deg); } .spa-brand-mark::after { transform: rotate(-45deg); } .spa-screen { padding: 28px 34px calc(112px + env(safe-area-inset-bottom)); } .spa-screen-head { min-height: 52px; margin-bottom: 22px; padding-bottom: 8px; border-bottom: 1px solid var(--line); } .spa-screen-back, .spa-share, .aux-btn, .label, .kicker, .spa-list-section, .search-summary, .history-origin, .scan-batch .kicker, .spa-loading-inner, .spa-loading-time, .spa-score-method-link { font-family: var(--f-sans); letter-spacing: 0; } .spa-screen-back, .spa-share { color: var(--ink-3); font-size: 12px; font-weight: 600; text-transform: none; } .spa-screen-back:hover, .spa-share:hover { color: var(--ink); } .w-h, .w-title, .spa-product-hero .name, .spa-cand.large .name { font-family: var(--f-serif); font-weight: 400; letter-spacing: 0; } .w-h { font-size: 34px; line-height: 1.12; } .w-txt { color: var(--ink-2); font-size: 14px; line-height: 1.58; } .w-sub { color: var(--ink-3); font-size: 13px; } .w-btn { min-height: 48px; border: 1px solid var(--ink); border-radius: 5px; background: var(--card); color: var(--ink); font-family: var(--f-sans); font-size: 13px; font-weight: 650; letter-spacing: 0; transition: transform .16s ease, background-color .16s ease, color .16s ease, box-shadow .16s ease; } .w-btn.primary { background: var(--ink); color: var(--card); box-shadow: 0 10px 22px rgba(8, 10, 9, .09); } .w-btn:hover { transform: translateY(-1px); } .w-btn.primary:hover { background: #252926; } .w-btn:active { transform: translateY(0); } .aux-btn { color: var(--ink-3); font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none; } .spa-app :focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; box-shadow: 0 0 0 6px rgba(239, 127, 18, .28); } .scan-intro { padding: 8px 0 16px; } .scan-intro .w-h { margin: 0 0 9px; font-family: var(--f-serif); font-size: 36px; font-weight: 400; line-height: 1.1; } .scan-intro .w-txt { max-width: 480px; color: var(--ink-2); font-size: 15px; } .viewfinder { margin: 4px 0 20px; border: 1px solid #242724; border-radius: 10px; background: #0d0f0e; box-shadow: 0 22px 48px rgba(12, 15, 13, .14); } .viewfinder-corner { width: 36px; height: 36px; border-width: 2px; border-color: rgba(255, 255, 255, .9); } .viewfinder-corner.tl { top: 20px; left: 20px; } .viewfinder-corner.tr { top: 20px; right: 20px; } .viewfinder-corner.bl { bottom: 20px; left: 20px; } .viewfinder-corner.br { right: 20px; bottom: 20px; } .viewfinder-hint { color: rgba(255, 255, 255, .62); font-family: var(--f-sans); font-size: 11px; font-weight: 600; letter-spacing: .05em; } .viewfinder.camera-idle video { display: none; } .scan-entry-actions { gap: 10px; margin-bottom: 12px; } .scan-entry-actions .w-btn { min-height: 48px; padding: 10px 12px; font-size: 13px; } .shutter-row { padding: 10px 0 20px; } .shutter-btn { width: 78px; height: 78px; border-width: 2px; box-shadow: 0 8px 24px rgba(8, 10, 9, .1); } .shutter-btn::after { width: 60px; height: 60px; } .shutter-caption { color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; letter-spacing: 0; } .scan-privacy-note { color: var(--ink-3); font-size: 11px; } .scan-batch { border-radius: 8px; background: rgba(13, 15, 14, .82); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); } .scan-batch .title { font-family: var(--f-serif); font-size: 20px; letter-spacing: 0; } .scan-thumb, .scan-thumb span, .scan-thumb button { border-radius: 5px; } .spa-tabbar { width: min(1040px, 100vw); padding: 8px 10px calc(8px + env(safe-area-inset-bottom)); border-top-color: rgba(174, 182, 176, .78); background: rgba(253, 253, 251, .96); box-shadow: 0 -16px 36px rgba(19, 25, 21, .075); -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px); } .spa-tabbar a { position: relative; min-height: 52px; justify-content: center; gap: 5px; border-radius: 6px; color: var(--ink-4); font-family: var(--f-sans); font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none; } .spa-tabbar a.on { color: var(--ink); background: var(--paper-2); } .spa-tabbar a.on::before { content: ""; position: absolute; top: 5px; left: 50%; width: 4px; height: 4px; border-radius: 50%; background: var(--ok); transform: translateX(-50%); } .spa-tabbar a span:first-child { font-size: 17px; } .w-score { --sc: var(--ok); border: 1.5px solid var(--sc); background: rgba(255, 255, 255, .84); color: var(--ink); font-family: var(--f-serif); font-style: normal; font-weight: 400; letter-spacing: 0; box-shadow: inset 0 0 0 5px rgba(255, 255, 255, .64); } .w-score.big { width: 94px; height: 94px; border-width: 2px; font-size: 41px; } .w-score.sm { width: 50px; height: 50px; font-size: 20px; } .w-score.xs { width: 44px; height: 44px; font-size: 15px; } .spa-product-hero { gap: 0; margin: 0 0 34px; padding: 24px; border: 1px solid #cbd1cd; border-radius: 10px; background: var(--card); box-shadow: 0 24px 56px rgba(18, 24, 20, .08); } .spa-product-hero .img { width: 100%; max-width: none; min-height: 340px; margin: 0 0 18px; padding: 18px; overflow: hidden; border: 0; border-radius: 8px; background: #f4f2ed; } .spa-product-hero .img img { max-height: 520px; filter: drop-shadow(0 18px 16px rgba(22, 18, 13, .09)); } .product-gallery { gap: 7px; padding-bottom: 16px; } .product-gallery button { flex-basis: 58px; width: 58px; height: 58px; border-color: var(--line-2); border-radius: 6px; background: #f7f6f2; } .product-gallery button.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); } .spa-product-hero .brand { margin-top: 2px; color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; font-weight: 700; letter-spacing: .04em; } .spa-product-hero .name { margin: 0; font-size: 34px; line-height: 1.14; } .spa-title-score-row { gap: 24px; margin: 10px 0 0; align-items: center; } .spa-score-method-link { gap: 8px; color: var(--ink-3); font-size: 10px; font-weight: 600; } .spa-score-method-link > span:last-child { max-width: 100px; text-align: center; } .spa-data-pills { gap: 8px; margin: -14px 0 26px; } .spa-product-hero > .spa-product-facts { margin: 18px 0 0; } .spa-data-pills span { padding: 7px 10px; border-color: var(--line); border-radius: 5px; background: var(--paper-2); color: var(--ink-2); font-family: var(--f-sans); font-size: 10px; font-weight: 600; letter-spacing: 0; text-transform: none; } .spa-section-head { margin: 38px 0 12px; padding-top: 28px; border-top: 1px solid var(--line-strong, var(--line-2)); color: var(--ink); font-family: var(--f-serif); font-size: 25px; font-weight: 400; letter-spacing: 0; line-height: 1.18; text-transform: none; } .spa-section-head .count { color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; } .spa-ing { grid-template-columns: 12px minmax(0, 1fr) 62px 18px; gap: 14px; min-height: 68px; padding: 13px 4px; border-bottom-color: var(--line); transition: background-color .14s ease; } .spa-ing:hover { background: var(--paper-2); } .spa-ing .dot { width: 7px; height: 7px; } .spa-ing > div { display: grid; grid-template-columns: minmax(190px, 1.05fr) minmax(160px, .95fr); gap: 18px; align-items: center; } .spa-ing .n { color: var(--ink); font-size: 14px; font-weight: 650; line-height: 1.35; } .spa-ing .role { margin: 0; color: var(--ink-3); font-size: 13px; line-height: 1.4; } .spa-ing .r { color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; font-weight: 600; letter-spacing: 0; } .spa-ing .toggle { color: var(--ink-3); font-family: var(--f-sans); font-size: 15px; } .spa-price-row { min-height: 62px; padding: 14px 4px; font-size: 14px; } .spa-price-row .store { font-weight: 600; } .spa-price-row .store small { color: var(--ink-3); font-size: 11px; } .spa-price-row .price { font-family: var(--f-serif); font-size: 20px; } .product-description { margin-top: 26px; border-color: var(--line); } .product-description h2, .product-description summary { font-family: var(--f-sans); font-size: 12px; font-weight: 650; letter-spacing: 0; text-transform: none; } .product-decision { border-left-color: var(--ok); border-radius: 0 7px 7px 0; background: var(--ok-soft); } .spa-search { grid-template-columns: auto minmax(0, 1fr); gap: 12px; margin: 8px 0 14px; padding: 8px 15px; border: 1px solid var(--line-2); border-radius: 8px; background: var(--card); box-shadow: 0 12px 28px rgba(18, 24, 20, .055); } .spa-search .icon { color: var(--ink); font-size: 20px; } .spa-search input { min-height: 48px; font-family: var(--f-sans); font-size: 16px; } .search-controls { gap: 12px; margin-bottom: 6px; padding: 12px 0 16px; border-bottom-color: var(--line); } .search-controls label { color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none; } .search-controls select, .history-search { border-color: var(--line-2); border-radius: 5px; background: var(--card); font-family: var(--f-sans); } .search-summary { padding: 16px 0 5px; color: var(--ink-3); font-size: 12px; font-weight: 600; } .spa-list-row { grid-template-columns: 70px minmax(0, 1fr) auto; gap: 16px; min-height: 98px; padding: 14px 4px; border-bottom-color: var(--line); transition: background-color .14s ease; } .spa-list-row:hover { background: var(--paper-2); } .spa-list-row .thumb { width: 70px; height: 76px; overflow: hidden; border: 0; border-radius: 6px; background: #f4f2ed; } .spa-list-row .brand { color: var(--ink-3); font-family: var(--f-sans); font-size: 10px; font-weight: 700; letter-spacing: .04em; } .spa-list-row .name { margin-top: 3px; font-family: var(--f-serif); font-size: 17px; font-weight: 400; line-height: 1.25; } .spa-list-row > div > div[style] { margin-top: 6px !important; color: var(--ink-3) !important; font-size: 12px !important; line-height: 1.45 !important; } .spa-list-row .arrow { color: var(--ink-3); font-family: var(--f-sans); font-size: 15px; } .search-row-tail { gap: 10px; } .spa-cand { margin-bottom: 12px; padding: 14px; border-color: var(--line-2); border-radius: 8px; box-shadow: 0 12px 26px rgba(18, 24, 20, .045); } .spa-cand.large { min-height: 148px; padding: 16px; border-radius: 9px; } .spa-cand.large .img { overflow: hidden; border: 0; border-radius: 7px; background: #f4f2ed; } .spa-cand.large .brand, .spa-cand.large .rank, .spa-cand.large .ref { font-family: var(--f-sans); letter-spacing: 0; } .spa-cand.large .name { font-size: 21px; line-height: 1.18; } .spa-cand.large .open-card { font-family: var(--f-sans); font-size: 11px; font-weight: 650; letter-spacing: 0; text-transform: none; } .spa-ocr-list { padding: 16px; border-color: var(--line); border-radius: 7px; background: var(--paper-2); font-family: var(--f-sans); font-size: 12px; } .search-empty, .spa-empty { margin-top: 18px; padding: 30px 26px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); } .search-examples button, .history-filters button { border-color: var(--line-2); border-radius: 5px; background: var(--card); font-family: var(--f-sans); } .history-filters { gap: 8px; padding-bottom: 10px; } .history-filters button { font-size: 12px; font-weight: 600; } .history-filters button.on { background: var(--ink); border-color: var(--ink); } .history-row { border-bottom-color: var(--line); } .history-origin, .history-no-score { color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; } .spa-loading { background: rgba(246, 247, 244, .88); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); } .spa-loading-card { border-color: var(--line-2); border-radius: 9px; background: var(--card); box-shadow: 0 26px 70px rgba(18, 24, 20, .14); } .spa-loading-inner { color: var(--ink); font-family: var(--f-serif); font-size: 22px; letter-spacing: 0; text-transform: none; } .spa-progress { height: 2px; } .spa-toast { border-radius: 7px; box-shadow: 0 18px 42px rgba(8, 10, 9, .18); } .spa-footer { padding: 30px 24px; color: var(--ink-3); font-family: var(--f-sans); font-size: 11px; letter-spacing: 0; } .spa-footer a { color: var(--ink); } @media (min-width: 860px) { .spa-tabbar { position: fixed; top: 0; right: auto; bottom: auto; left: 50%; width: min(1040px, 100vw); max-width: 100vw; min-height: 72px; display: grid; grid-template-columns: repeat(3, auto); justify-content: end; gap: 28px; padding: 0 32px; border: 0; background: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; transform: translateX(-50%); pointer-events: none; } .spa-tabbar[hidden] { display: none !important; } .spa-tabbar a { min-width: 74px; min-height: 72px; padding: 0 6px; border-radius: 0; background: transparent; font-size: 12px; pointer-events: auto; } .spa-tabbar a span:first-child { display: none; } .spa-tabbar a.on { background: transparent; } .spa-tabbar a.on::before { top: auto; bottom: 0; width: 100%; height: 2px; border-radius: 0; } .spa-screen[data-route="scan"].on { min-height: calc(100svh - 72px); display: grid; grid-template-columns: minmax(320px, .76fr) minmax(440px, 1.24fr); grid-template-areas: "intro camera" "actions camera" "shutter camera" "privacy camera"; grid-template-rows: auto auto auto 1fr; gap: 14px 44px; align-content: center; justify-content: stretch; padding-top: 34px; padding-bottom: 96px; } .spa-screen[data-route="scan"] .scan-intro { grid-area: intro; align-self: end; } .spa-screen[data-route="scan"] .scan-entry-actions { grid-area: actions; } .spa-screen[data-route="scan"] .shutter-row { grid-area: shutter; } .spa-screen[data-route="scan"] .scan-privacy-note { grid-area: privacy; align-self: start; max-width: 360px; margin: 0; text-align: left; } .spa-screen[data-route="scan"] .viewfinder { grid-area: camera; width: min(100%, 510px); min-height: 570px; max-height: min(680px, calc(100svh - 150px)) !important; justify-self: end; align-self: center; margin: 0; } .spa-product-hero { display: grid; grid-template-columns: minmax(300px, .86fr) minmax(0, 1.14fr); grid-template-areas: "visual brand" "visual title" "visual facts" "gallery facts"; gap: 10px 42px; align-items: start; padding: 30px; } .spa-product-hero .img { grid-area: visual; min-height: 420px; margin: 0; } .spa-product-hero > .product-gallery { grid-area: gallery; padding: 2px 0 0; } .spa-product-hero > .brand { grid-area: brand; align-self: end; margin-top: 24px; } .spa-product-hero > .spa-title-score-row { grid-area: title; align-self: start; margin-top: 8px; } .spa-product-hero > .spa-product-facts { grid-area: facts; align-self: start; margin-top: 18px; } .spa-product-hero .name { font-size: 40px; } } @media (max-width: 859px) { body:has(.spa-app) { background: var(--paper); } .spa-brandbar { background: var(--paper); -webkit-backdrop-filter: none; backdrop-filter: none; } .spa-app { max-width: 820px; border-inline: 0; box-shadow: none; } } @media (max-width: 600px) { html, body { font-size: 15px; } .spa-brandbar { min-height: 64px; padding: 0 18px; background: var(--paper); -webkit-backdrop-filter: none; backdrop-filter: none; } .spa-brand { gap: 11px; font-size: 27px; } .spa-brand-mark { width: 28px; height: 28px; background: linear-gradient(var(--ink), var(--ink)) center / 3px 28px no-repeat, linear-gradient(var(--ink), var(--ink)) center / 28px 3px no-repeat; } .spa-brand-mark::before, .spa-brand-mark::after { left: 13px; width: 3px; height: 28px; } .spa-screen { padding-top: 20px; padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); padding-bottom: calc(102px + env(safe-area-inset-bottom)); } .spa-screen[data-route="scan"] { min-height: calc(100svh - 64px); padding-top: 18px; } .spa-screen-head { min-height: 46px; margin-bottom: 16px; } .scan-intro { padding-top: 0; padding-bottom: 10px; } .scan-intro .w-h { font-size: 28px; } .scan-intro .w-txt { font-size: 14px; } .viewfinder { aspect-ratio: 1; max-height: none !important; border-radius: 9px; box-shadow: 0 16px 34px rgba(12, 15, 13, .12); } .viewfinder-corner { width: 30px; height: 30px; } .viewfinder-corner.tl { top: 16px; left: 16px; } .viewfinder-corner.tr { top: 16px; right: 16px; } .viewfinder-corner.bl { bottom: 16px; left: 16px; } .viewfinder-corner.br { right: 16px; bottom: 16px; } .scan-entry-actions .w-btn { font-size: 12px; } .shutter-btn { width: 68px; height: 68px; } .shutter-btn::after { width: 52px; height: 52px; } .shutter-row { padding-top: 6px; padding-bottom: 12px; } .spa-product-hero { margin-bottom: 28px; padding: 16px; border-radius: 9px; } .spa-product-hero .img { min-height: 300px; padding: 12px; } .spa-product-hero .name { font-size: 28px; } .spa-title-score-row { gap: 14px; align-items: center; } .spa-title-score-row .w-score, .w-score.big { width: 74px; height: 74px; font-size: 32px; } .spa-data-pills { margin-top: -10px; } .spa-section-head { margin-top: 32px; padding-top: 24px; font-size: 23px; } .spa-ing { grid-template-columns: 10px minmax(0, 1fr) 48px 14px; gap: 10px; min-height: 70px; padding: 12px 2px; } .spa-ing > div { display: block; } .spa-ing .n { font-size: 13px; } .spa-ing .role { margin-top: 4px; font-size: 12px; } .spa-ing .r { font-size: 10px; } .spa-list-row { grid-template-columns: 60px minmax(0, 1fr) auto; gap: 12px; min-height: 92px; padding: 12px 2px; } .spa-list-row .thumb { width: 60px; height: 68px; } .spa-list-row .name { font-size: 16px; } .spa-list-row > div > div[style] { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; font-size: 11px !important; } .w-score.xs { width: 42px; height: 42px; font-size: 14px; } .spa-cand.large { padding: 12px; } .spa-cand.large .name { font-size: 18px; } .spa-tabbar { width: 100vw; } } @media (max-width: 360px) { .spa-brandbar { padding-inline: 15px; } .spa-brand { font-size: 25px; } .spa-screen { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); } .scan-intro .w-h { font-size: 26px; } .scan-entry-actions { gap: 7px; } .spa-product-hero .img { min-height: 250px; } .spa-product-hero .name { font-size: 25px; } .spa-list-row { grid-template-columns: 52px minmax(0, 1fr) auto; gap: 9px; } .spa-list-row .thumb { width: 52px; height: 62px; } .spa-list-row .name { font-size: 15px; } } .spa-app h1[tabindex="-1"]:focus, .spa-app h1[tabindex="-1"]:focus-visible { outline: none; box-shadow: none; }