:root {
  --bg-primary: #000000;
  --bg-secondary: #0a0a0f;
  --bg-tertiary: #14141f;
  --bg-card: #1a1a2e;
  --text-primary: #ffffff;
  --text-secondary: #a0a0b0;
  --text-muted: #606070;
  --accent-primary: #00d4ff;
  --accent-secondary: #00ff88;
  --danger: #ff4466;
  --focus-ring: #00d4ff;
  --focus-glow: rgba(0, 212, 255, 0.4);
  --listening: #ff4466;
  --listening-glow: rgba(255, 68, 102, 0.5);
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  width: 100%;
  height: 100%;
  background: var(--bg-primary);
  overflow: hidden;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color: var(--text-primary);
}

/* Design canvas is 600x600 (the glasses display). For preview in smaller
 * panes we shrink the whole app uniformly via --app-scale, set by JS. */
#app {
  width: 600px;
  height: 600px;
  position: relative;
  transform: scale(var(--app-scale, 1));
  transform-origin: top left;
}

.screen {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  position: absolute;
  top: 0;
  left: 0;
}
.screen.hidden { display: none; }

/* --- Address Bar (top header) --- */
.address-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  background: var(--bg-secondary);
  flex-shrink: 0;
  border-bottom: 1px solid var(--bg-tertiary);
}
.address-bar .text-input {
  flex: 1;
  padding: 14px 16px;
  font-size: 18px;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border-radius: var(--radius-md);
  border: 2px solid transparent;
  min-width: 0;
}
.address-bar .text-input:focus {
  border-color: var(--focus-ring);
  box-shadow: 0 0 20px var(--focus-glow);
  outline: none;
}
.address-bar .text-input::placeholder { color: var(--text-muted); }

.icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 52px;
  min-width: 76px;
  padding: 0 16px;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.icon-btn:focus {
  outline: none;
  border-color: var(--focus-ring);
  box-shadow: 0 0 20px var(--focus-glow);
  background: var(--bg-card);
}
.icon-btn.primary {
  background: var(--accent-primary);
  color: #0a0a0f;
}
.icon-btn.primary:focus { background: #33ddff; }

.icon-label { font-size: 15px; font-weight: 600; line-height: 1; }

/* Star (Bookmarks) button in the address bar — narrow, icon-only. */
.star-btn {
  min-width: 0;
  width: 52px;
  padding: 0;
}
.star-btn .icon-label {
  font-size: 22px;
  line-height: 1;
}
.star-btn.has-bookmarks .icon-label {
  color: var(--accent-warm);
}

/* --- Mic indicator dot --- */
.mic-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--text-secondary);
  flex-shrink: 0;
}
.icon-btn.listening {
  border-color: var(--listening);
  box-shadow: 0 0 24px var(--listening-glow);
  background: var(--bg-card);
}
.icon-btn.listening .mic-dot {
  background: var(--listening);
  animation: pulse 1s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.5); opacity: 0.6; }
}

/* --- Focusable base --- */
.focusable {
  /* Press uses display-guidelines easing (100ms, cubic-bezier(0.68, 0, 0.29, 1)).
   * Other state changes use a gentler ease. */
  transition:
    transform 110ms cubic-bezier(0.68, 0, 0.29, 1),
    background-color 150ms ease,
    border-color 150ms ease,
    box-shadow 150ms ease,
    filter 110ms ease;
  cursor: pointer;
}

/* Press feedback for buttons / list items (not text inputs — scaling those is jarring).
 * `:active` covers pointer presses; `.pressed` is applied via JS for Enter-key activation
 * since :active doesn't fire on keyboard.
 *
 * NOTE on additive display: a press feedback that only shifts between dark
 * grays (e.g. #14141f → #1a1a2e) is effectively invisible on the glasses
 * since both colors emit ~no light. Dark buttons therefore invert to a
 * bright surface on press so the punch is obvious. */
.focusable:not(input):active,
.focusable:not(input).pressed {
  transform: scale(0.94);
}

/* Dark icon buttons (e.g. Voice) → invert to cyan-on-black for a bright flash. */
.icon-btn:active,
.icon-btn.pressed {
  background: var(--accent-primary);
  color: #0a0a0f;
  border-color: var(--accent-primary);
}
.icon-btn:active .mic-dot,
.icon-btn.pressed .mic-dot {
  background: #0a0a0f;
}

/* Primary (already cyan) → flash to white. */
.icon-btn.primary:active,
.icon-btn.primary.pressed {
  background: var(--text-primary);
  color: #0a0a0f;
  border-color: var(--text-primary);
}

/* Result / recent items → bright cyan ring + brighter card so the flash
 * shows up without trying to invert nested text colors. */
.result-item:active,
.result-item.pressed,
.recent-item:active,
.recent-item.pressed {
  background: var(--bg-card);
  border-color: var(--accent-primary);
  box-shadow: 0 0 24px var(--focus-glow), inset 0 0 0 1px var(--accent-primary);
}

/* --- Content --- */
.content {
  flex: 1;
  padding: 14px 16px 16px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.status-hint {
  font-size: 14px;
  color: var(--text-secondary);
  text-align: center;
  padding: 8px 4px;
}
.status-hint.error { color: var(--danger); }
.status-hint.live {
  color: var(--listening);
  font-weight: 500;
}

/* --- Phone pair hint + relay status dot --- */
.phone-pair {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 4px;
  font-size: 13px;
  color: var(--text-secondary);
}
.phone-pair b {
  color: var(--accent-primary);
  font-weight: 600;
}
.relay-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--text-muted);
  flex-shrink: 0;
  transition: background 200ms ease, box-shadow 200ms ease;
}
.relay-dot.connected {
  background: var(--accent-secondary);
  box-shadow: 0 0 8px var(--accent-secondary);
}

/* Brief flash when a query arrives from the phone relay. */
.text-input.relay-flash {
  border-color: var(--accent-secondary);
  box-shadow: 0 0 30px rgba(0, 255, 136, 0.6);
}

/* --- Web view (in-app browser) --- */
.web-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
  flex-shrink: 0;
}
.back-btn {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 600;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: inherit;
  line-height: 1;
}
.back-btn:focus {
  outline: none;
  border-color: var(--focus-ring);
  box-shadow: 0 0 20px var(--focus-glow);
  background: var(--bg-card);
}
.back-btn:active,
.back-btn.pressed {
  background: var(--accent-primary);
  color: #0a0a0f;
  border-color: var(--accent-primary);
}
.web-url {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--accent-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 4px;
}
/* Outer scroll container: our document scrolls a tall iframe up/down on
 * D-pad arrow keys. See web-view comment in index.html for rationale.
 *
 * The container itself is focusable — it joins the standard parent focus
 * cycle (Back ↔ web pane ↔ +Save). When focused, the inset focus ring
 * tells the user they've selected the pane; pressing Enter then transfers
 * focus INTO the iframe (entering "iframe spatial-nav mode"). */
.web-frame-container {
  flex: 1;
  width: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--bg-primary);
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  position: relative;
  /* Reserve border space so focus doesn't shift the iframe.
   * box-sizing keeps the container's outer dimensions stable. */
  border: 4px solid transparent;
  box-sizing: border-box;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
/* Two-state visual for the web pane.
 *
 *   "Selected, not entered" (.focusable:focus, no .iframe-mode class):
 *     Cyan border, matching the other parent-row buttons. Tells the
 *     user the pane is the current focus target; pressing Enter will
 *     enter iframe spatial-nav mode, Up/Down still cycles to the
 *     adjacent buttons.
 *
 *   "Entered" (.iframe-mode class, regardless of which descendant has
 *   focus):
 *     Green border + green glow. Distinct from the cyan elsewhere in
 *     the UI so the user can see at a glance that D-pad arrows are now
 *     doing WebView spatial-nav inside the iframe — they need to press
 *     Escape before arrows will cycle the parent buttons again.
 *
 * We DO NOT use :focus-within for the cyan rule: when the iframe
 * descendant has focus (iframe-mode), :focus-within would still match
 * the container, so cyan and green would conflict. The .iframe-mode
 * class is the single source of truth for "entered" state. */
.web-frame-container.focusable:focus {
  outline: none;
  border-color: var(--accent-primary);
  box-shadow: 0 0 24px var(--focus-glow);
}
.web-frame-container.focusable.iframe-mode,
.web-frame-container.focusable.iframe-mode:focus,
.web-frame-container.focusable.iframe-mode:focus-within {
  outline: none;
  border-color: var(--accent-secondary);
  box-shadow: 0 0 24px rgba(0, 255, 136, 0.45);
}
.web-frame {
  display: block;
  width: 100%;
  /* Tall enough to render even long, image-heavy homepages (nintendo.co.jp
   * etc.) without clipping. The browser lazy-renders off-screen content so
   * memory cost is negligible — render layers only allocate as the user
   * scrolls down. */
  height: 50000px;
  border: 0;
  background: #ffffff;
}
.web-fallback {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 32px;
  text-align: center;
}
.web-fallback-icon {
  font-size: 40px;
  color: var(--warning);
}
.web-fallback-title {
  font-size: 18px;
  font-weight: 600;
}
.web-fallback-desc {
  font-size: 14px;
  color: var(--text-secondary);
  max-width: 400px;
}

/* Bookmark / save button in web-bar (sized to fit alongside back + url). */
.bookmark-btn {
  min-width: 0;
  padding: 0 12px;
  height: 40px;
  font-size: 13px;
  flex-shrink: 0;
}

/* --- Wikipedia reader view ---
 * Rendered in our document (not iframe), so every link is a real focusable
 * element. Dark theme overrides Wikipedia's default styling. */
.article-container {
  flex: 1;
  width: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--bg-primary);
  color: var(--text-primary);
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
}
.article-body {
  padding: 16px 18px 32px;
  font-size: 15px;
  line-height: 1.55;
  width: 100%;
  max-width: 100%;
  word-wrap: break-word;
  overflow-wrap: break-word;
}
/* Hard cap on any nested element — Wikipedia inlines lots of fixed widths
 * (infoboxes set width:22em, images get explicit pixel widths, etc.) that
 * would otherwise blow past the 600px viewport. */
.article-body * {
  max-width: 100% !important;
  box-sizing: border-box;
}
.article-body h1 { font-size: 22px; margin: 18px 0 8px; line-height: 1.25; }
.article-body h2 { font-size: 19px; margin: 22px 0 8px; padding-bottom: 4px; border-bottom: 1px solid var(--bg-tertiary); line-height: 1.3; }
.article-body h3 { font-size: 17px; margin: 18px 0 6px; }
.article-body h4 { font-size: 15px; margin: 14px 0 4px; color: var(--text-secondary); }
.article-body p { margin: 8px 0; }
.article-body ul, .article-body ol { margin: 8px 0 8px 22px; }
.article-body li { margin: 4px 0; }
.article-body img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 8px auto;
  border-radius: 6px;
}
.article-body figure { margin: 12px 0; }
.article-body figcaption {
  font-size: 12px;
  color: var(--text-secondary);
  padding: 4px 8px;
  text-align: center;
}
.article-body table {
  font-size: 12px;
  border-collapse: collapse;
  margin: 12px 0;
  width: 100%;
  display: block;
  overflow-x: auto;
}
.article-body td, .article-body th {
  padding: 4px 6px;
  border: 1px solid var(--bg-tertiary);
  vertical-align: top;
}
.article-body th {
  background: var(--bg-tertiary);
  color: var(--text-primary);
  text-align: left;
}
.article-body blockquote {
  margin: 10px 0;
  padding-left: 12px;
  border-left: 3px solid var(--bg-tertiary);
  color: var(--text-secondary);
  font-style: italic;
}
.article-body code, .article-body pre {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 13px;
  background: var(--bg-tertiary);
  border-radius: 4px;
  padding: 1px 4px;
}
.article-body pre { padding: 8px; overflow-x: auto; }
.article-body hr { border: 0; border-top: 1px solid var(--bg-tertiary); margin: 16px 0; }

/* Links: cyan with a dotted underline.
 *
 * Focus indicator MUST work on the glasses' additive display, where black
 * (#000) emits no light at all. A focus style of "dark text on bright
 * cyan background" appears as a featureless cyan blob — you can't tell
 * you're on a link. So focus keeps the text bright (white) and adds a
 * bright cyan outline + subtle cyan wash for clear contrast. */
.article-body a {
  color: var(--accent-primary);
  text-decoration: none;
  border-bottom: 1px dotted rgba(0, 212, 255, 0.45);
  border-radius: 3px;
  padding: 0 2px;
  margin: 0 -2px;
  transition: background 120ms ease, box-shadow 120ms ease, color 120ms ease;
}
.article-body a:focus {
  outline: none;
  color: #ffffff;
  background: rgba(0, 212, 255, 0.22);
  border-bottom-color: var(--accent-primary);
  box-shadow:
    0 0 0 2px var(--accent-primary),
    0 0 18px var(--focus-glow);
}
.article-body a.external {
  border-bottom-style: dashed;
}

/* External links get a small badge so the user knows they'll be iframed
 * (and may or may not load), not navigated in the reader. */
.article-body a.external::after {
  content: ' \2197';
  font-size: 0.85em;
  opacity: 0.7;
}

/* Wikipedia-specific cleanups: hide chrome elements that don't belong on
 * a 600x600 reader. */
.article-body .mw-editsection,
.article-body .reference,
.article-body .hatnote,
.article-body .ambox,
.article-body .navbox,
.article-body .vertical-navbox,
.article-body .metadata,
.article-body .mw-empty-elt,
.article-body sup.reference,
.article-body .reflist {
  display: none;
}

/* Compact infoboxes into a readable card. !important is required because
 * Wikipedia inlines width / float / cellpadding on these tables. */
.article-body .infobox,
.article-body table.infobox {
  font-size: 12px !important;
  background: var(--bg-secondary) !important;
  border-radius: 8px !important;
  border: 0 !important;
  margin: 12px 0 !important;
  padding: 8px !important;
  width: 100% !important;
  max-width: 100% !important;
  float: none !important;
  display: block !important;
  overflow-x: auto;
}
.article-body .infobox img,
.article-body table.infobox img {
  max-width: 100% !important;
  height: auto !important;
}
/* Wikipedia's "float right" sidebar boxes — clear and inline them too. */
.article-body [style*="float:right"],
.article-body [style*="float: right"],
.article-body [style*="float:left"],
.article-body [style*="float: left"] {
  float: none !important;
  width: 100% !important;
  margin: 12px 0 !important;
}

.article-status {
  padding: 24px 16px;
  text-align: center;
  font-size: 14px;
  color: var(--text-secondary);
}
.article-status.error { color: var(--danger); }

/* Byline / site name shown above the reader-extracted content. */
.reader-meta {
  font-size: 12px;
  color: var(--text-secondary);
  margin: 0 0 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--bg-tertiary);
  letter-spacing: 0.02em;
}

/* Screenshot fallback view: the PNG fills the article-body width so the
 * outer scroll container handles overflow. We render at viewport width
 * on the server so display-scale matches the iframe path. */
.screenshot-image {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  border-radius: var(--radius-md);
  background: var(--bg-tertiary);
}

/* "Read as text →" chip at the top of the screenshot view. Lets the
 * user bounce into reader extraction when they want focusable links
 * rather than a static image. */
.screenshot-readtext {
  display: inline-block;
  padding: 8px 14px;
  margin: 0 0 12px;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.screenshot-readtext:focus,
.screenshot-readtext.pressed {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-elevated, var(--bg-tertiary));
}

/* Bookmarks list items reuse .recent-item / .result-item patterns. */
.bookmark-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: 15px;
}
.bookmark-row:focus {
  outline: none;
  border-color: var(--focus-ring);
  background: var(--bg-card);
  box-shadow: 0 0 20px var(--focus-glow);
}
.bookmark-icon {
  color: var(--accent-warm);
  font-size: 18px;
  flex-shrink: 0;
}
.bookmark-icon.folder-icon {
  color: var(--accent-primary);
}

/* Destructive button (e.g. "Clear all bookmarks"). Outline-style by default
 * so it doesn't dominate the list visually; fills in red on focus and
 * stays red while waiting for the second confirmation tap. */
.danger-btn {
  display: block;
  width: calc(100% - 4px);
  margin: 24px 2px 8px;
  padding: 14px 16px;
  background: transparent;
  color: var(--danger);
  border: 2px solid rgba(255, 68, 102, 0.4);
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease,
              border-color 150ms ease, box-shadow 150ms ease,
              transform 110ms cubic-bezier(0.68, 0, 0.29, 1);
}
.danger-btn:focus {
  outline: none;
  border-color: var(--danger);
  background: rgba(255, 68, 102, 0.15);
  box-shadow: 0 0 18px rgba(255, 68, 102, 0.45);
}
.danger-btn:active,
.danger-btn.pressed {
  transform: scale(0.96);
}
.danger-btn.confirming {
  background: var(--danger);
  color: white;
  border-color: var(--danger);
}
.bookmark-text {
  flex: 1;
  min-width: 0;
}
.bookmark-title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bookmark-host {
  font-size: 12px;
  color: var(--accent-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 2px;
}

/* --- Section labels --- */
.section-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 4px 4px 6px;
}

/* --- Results list --- */
.list-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.result-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  text-align: left;
  padding: 14px 16px;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  font-family: inherit;
}
.result-item:focus {
  outline: none;
  border-color: var(--focus-ring);
  box-shadow: 0 0 20px var(--focus-glow);
  background: var(--bg-card);
}

.result-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--accent-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: 700;
  flex-shrink: 0;
}
.result-icon.google { background: var(--accent-primary); color: #0a0a0f; }
.result-icon.wiki { background: #2a2a3a; color: #ffffff; }
.result-icon.ddg { background: #2a2a3a; color: var(--accent-secondary); }

.result-content { flex: 1; min-width: 0; }
.result-title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.result-url {
  font-size: 12px;
  color: var(--accent-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4px;
}
.result-desc {
  font-size: 13px;
  color: var(--text-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* --- Loading --- */
.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 32px;
}
.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid var(--bg-tertiary);
  border-top-color: var(--accent-primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-text {
  font-size: 15px;
  color: var(--text-secondary);
}

/* --- Recent searches --- */
.recent-section { display: flex; flex-direction: column; }
.recent-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  background: transparent;
  color: var(--text-secondary);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-family: inherit;
}
.recent-item:focus {
  outline: none;
  border-color: var(--focus-ring);
  background: var(--bg-tertiary);
  color: var(--text-primary);
}
.recent-item .recent-arrow {
  color: var(--text-muted);
  font-size: 16px;
  flex-shrink: 0;
}

.hidden { display: none !important; }
