/* Colour tokens are a straight port of ui/theme/Color.kt + Theme.kt's
   light/dark ColorScheme mapping - approximate readings from the Redat
   website screenshot (2026-07-20), NOT the exact brand hex values yet.
   Every colour in the app should flow through these variables, never a
   literal colour inline in a screen. */
:root {
  --redat-red: #c41f3a;
  --redat-red-dark: #9c1730;
  --redat-navy: #2b3a48;

  --color-primary: var(--redat-red);
  --color-on-primary: #ffffff;
  --color-secondary: var(--redat-navy);
  --color-on-secondary: #ffffff;
  --color-background: #f4f5f6;
  --color-on-background: #1e242b;
  --color-surface: #ffffff;
  --color-on-surface: #1e242b;
  --color-surface-variant: #e7e9eb;
  --color-on-surface-variant: #4b5560;
  --color-outline: #dfe2e5;
  --color-error: #b3261e;

  --shape-small: 8px;
  --shape-medium: 12px;

  /* Same amber in both themes on purpose - a "starred" indicator reads as
     gold regardless of light/dark surface colours, unlike the theme-mapped
     tokens above. */
  --color-favourite: #f2b90c;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-error: #f2b8b5;
    --color-on-primary: #1d2126;
    --color-on-secondary: #eef0f1;
    --color-background: #14171a;
    --color-on-background: #eef0f1;
    --color-surface: #1d2126;
    --color-on-surface: #eef0f1;
    --color-surface-variant: #262b31;
    --color-on-surface-variant: #aab1b8;
    --color-outline: #2c3339;
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--color-background);
  color: var(--color-on-background);
}

#app {
  display: flex;
  flex-direction: column;
  height: 100dvh;
}

button {
  font: inherit;
  color: inherit;
}

/* ---------- Top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-outline);
  flex: 0 0 auto;
  z-index: 20;
}

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: none;
  background: transparent;
  border-radius: 999px;
  cursor: pointer;
  flex: 0 0 auto;
}

.icon-button:hover {
  background: var(--color-surface-variant);
}

.icon-button:disabled {
  opacity: 0.35;
  cursor: default;
}

.icon-button:disabled:hover {
  background: transparent;
}

/* "Stellina" toggle on the catalog page viewer (see screens/catalogDetail.js)
   - amber whenever the current page is a favourite, same colour as the
   Favourites "Pages" carousel it feeds. */
.icon-button--favourited {
  color: var(--color-favourite);
}

.icon-button svg,
.drawer__item-icon,
.search-field__icon {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.search-field {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--color-surface-variant);
  border-radius: var(--shape-small);
  padding: 8px 12px;
}

.search-field__icon {
  fill: var(--color-primary);
  flex: 0 0 auto;
}

.search-field__input {
  flex: 1 1 auto;
  border: none;
  background: transparent;
  outline: none;
  font-size: 0.95rem;
  color: var(--color-on-surface);
}

/* ---------- Layout / drawer ---------- */

.layout {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

.content {
  flex: 1 1 auto;
  min-width: 0;
  overflow-y: auto;
  outline: none;
}

.scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 29;
}

.drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(300px, 80vw);
  background: var(--color-surface);
  transform: translateX(-100%);
  transition: transform 0.2s ease;
  z-index: 30;
  display: flex;
  flex-direction: column;
  box-shadow: 2px 0 12px rgba(0, 0, 0, 0.15);
}

.drawer--open {
  transform: translateX(0);
}

.drawer__title {
  display: flex;
  justify-content: center;
  padding: 20px 16px 12px;
}

.drawer__logo {
  /* The source logo's "REDAT" wordmark is solid black - illegible against
     the dark theme's drawer background without a light backdrop of its
     own. White matches --color-surface in light theme exactly, so this is
     a no-op there and only fixes contrast in dark theme. */
  height: 64px;
  width: auto;
  max-width: 100%;
  background: #ffffff;
  border-radius: 12px;
  padding: 8px 16px;
}

.drawer__list {
  list-style: none;
  margin: 0;
  padding: 4px 12px;
}

.drawer__list--scrollable {
  flex: 1 1 auto;
  overflow-y: auto;
}

.drawer__pinned {
  flex: 0 0 auto;
  border-top: 1px solid var(--color-outline);
  padding: 4px 12px;
}

.drawer__item {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 12px 16px;
  border: none;
  background: transparent;
  border-radius: 999px;
  text-align: left;
  cursor: pointer;
  margin-bottom: 4px;
}

.drawer__item:hover {
  background: var(--color-surface-variant);
}

.drawer__item--selected {
  background: color-mix(in srgb, var(--color-primary) 16%, transparent);
  color: var(--color-primary);
}

/* ---------- Generic building blocks ---------- */

.screen {
  padding: 16px;
}

.screen-title {
  font-size: 1.3rem;
  font-weight: 600;
  margin: 4px 0 12px;
}

.empty-state {
  color: var(--color-on-surface-variant);
  padding: 16px;
}

/* ---------- Debug screen ---------- */

.debug-log__actions {
  display: flex;
  gap: 8px;
  margin: 12px 0;
}

.debug-log__actions .button {
  flex: 0 0 auto;
}

.debug-log {
  background: var(--color-surface);
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-small);
  padding: 12px;
  font-family: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
  font-size: 0.8rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 60vh;
  overflow-y: auto;
  margin: 0;
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-medium);
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}

.card:hover {
  border-color: var(--color-primary);
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.list-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  margin: 6px 0;
}

.thumbnail {
  object-fit: cover;
  border-radius: 4px;
  flex: 0 0 auto;
  background: var(--color-surface-variant);
}

.list-row__title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 2px;
}

.list-row__subtitle {
  font-size: 0.85rem;
  color: var(--color-on-surface-variant);
  margin: 0;
}

.saved-notepad-row {
  display: flex;
  align-items: center;
  padding: 6px 4px 6px 16px;
  margin: 6px 0;
  gap: 4px;
  cursor: default;
}

.saved-notepad-row__body {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 0;
  cursor: pointer;
}

/* ---------- Carousels (Favourites) ---------- */

.carousel-section {
  margin-bottom: 20px;
}

.carousel-section__title {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 8px;
  padding: 0 16px;
}

.carousel {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 2px 16px 8px;
  scroll-snap-type: x proximity;
}

.carousel-card {
  flex: 0 0 auto;
  width: 150px;
  padding: 12px;
  scroll-snap-align: start;
}

.carousel-card__title {
  font-size: 0.9rem;
  margin: 8px 0 4px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.carousel-card__subtitle {
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
  margin: 0;
}

/* ---------- Dialogs ---------- */

dialog.confirm-dialog {
  border: none;
  border-radius: var(--shape-medium);
  padding: 0;
  max-width: 360px;
  width: calc(100vw - 48px);
  color: var(--color-on-surface);
  background: var(--color-surface);
}

dialog.confirm-dialog::backdrop {
  background: rgba(0, 0, 0, 0.4);
}

.confirm-dialog__form {
  padding: 20px;
}

.confirm-dialog__title {
  font-size: 1.1rem;
  margin: 0 0 8px;
}

.confirm-dialog__message {
  font-size: 0.92rem;
  color: var(--color-on-surface-variant);
  margin: 0 0 16px;
}

.confirm-dialog__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* iOS "how to install" steps (components/installInstructionsDialog.js) -
   same type scale/colour as .confirm-dialog__message, just numbered. */
.install-instructions__steps {
  font-size: 0.92rem;
  color: var(--color-on-surface-variant);
  margin: 0 0 16px;
  padding-left: 20px;
}

.install-instructions__steps li + li {
  margin-top: 6px;
}

.text-button {
  border: none;
  background: transparent;
  color: var(--color-on-surface-variant);
  padding: 8px 12px;
  border-radius: var(--shape-small);
  cursor: pointer;
  font-weight: 600;
}

.text-button:hover {
  background: var(--color-surface-variant);
}

.text-button--primary {
  color: var(--color-primary);
}

/* ---------- Forms ---------- */

.form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 480px;
}

.text-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.text-field label {
  font-size: 0.8rem;
  color: var(--color-on-surface-variant);
}

.text-field input,
.text-field select {
  padding: 10px 12px;
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-small);
  background: var(--color-surface);
  color: var(--color-on-surface);
  font-size: 0.95rem;
}

.text-field input:focus,
.text-field select:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: -1px;
}

.form-note {
  font-size: 0.8rem;
  color: var(--color-on-surface-variant);
  margin: 0;
}

/* ---------- Install banner (components/installBanner.js) ---------- */

/* #install-banner-root sits between the topbar and .layout in index.html,
   in normal document flow - empty (height 0) when there's nothing to show,
   no display:none toggling needed. */
.install-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--color-surface-variant);
  color: var(--color-on-surface-variant);
  border-bottom: 1px solid var(--color-outline);
}

.install-banner__icon {
  width: 22px;
  height: 22px;
  fill: var(--color-primary);
  flex: 0 0 auto;
}

.install-banner__text {
  flex: 1 1 auto;
  margin: 0;
  font-size: 0.85rem;
}

.install-banner__action {
  flex: 0 0 auto;
  padding: 8px 14px;
  white-space: nowrap;
}

.form-warning {
  font-size: 0.9rem;
  color: var(--color-error);
  margin: 0;
}

/* ---------- Contacts screen ---------- */

.contacts__company {
  font-size: 1.3rem;
  font-weight: 600;
  margin: 4px 0 20px;
}

.contacts__row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 16px;
}

.contacts__icon {
  width: 22px;
  height: 22px;
  fill: var(--color-on-surface-variant);
  flex: 0 0 auto;
  margin-top: 2px;
}

.contacts__text {
  margin: 0;
  line-height: 1.5;
}

/* ---------- About screen ---------- */

.about__section-title {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 20px 0 8px;
}

.about__section-title:first-child {
  margin-top: 4px;
}

.about__section-body {
  margin: 0;
  line-height: 1.5;
}

.about__section-body a {
  color: var(--color-primary);
}

/* ---------- Saved notepad edit screen ---------- */

.saved-notepad-edit {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.saved-notepad-edit__header {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px;
  flex: 0 0 auto;
}

.saved-notepad-edit__header .text-field {
  flex: 1 1 auto;
}

.saved-notepad-edit__rows {
  flex: 1 1 auto;
  overflow-y: auto;
  border-top: 1px solid var(--color-outline);
  border-bottom: 1px solid var(--color-outline);
}

.saved-notepad-edit__footer {
  display: flex;
  gap: 8px;
  padding: 16px;
  flex: 0 0 auto;
}

/* ---------- Catalog detail (PDF viewer) ---------- */

.pdf-viewer {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.pdf-viewer__page-area {
  flex: 1 1 auto;
  overflow: auto;
  background: var(--color-secondary);
  display: flex;
  padding: 8px;
  /* Baseline before any page has loaded/zoomed - catalogDetail.js's
     applyZoom() overrides this inline once a page is shown, switching to
     "pan-x pan-y" only while actually zoomed in (native horizontal panning
     otherwise steals a touch swipe from the JS swipe-to-change-page handler
     before it ever completes, see applyZoom()'s comment). "pan-y" alone
     still disables the browser's own pinch-zoom/double-tap-zoom here -
     catalogDetail.js's own pointer handlers drive zoom instead, scoped to
     just this viewer instead of the whole page (topbar/toolbar included). */
  touch-action: pan-y;
}

.pdf-viewer__page-image {
  background: #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
  display: block;
  max-width: none;
  /* Centers the page when it's smaller than the viewport (the common case
     at 1x zoom) without the classic flexbox align/justify-content:center
     pitfall: auto margins collapse to 0 instead of clipping the overflow
     unreachable once the image is bigger than the container (zoomed in),
     so scrolling in every direction still reaches the full image either way. */
  margin: auto;
}

.pdf-viewer__message {
  color: var(--color-on-secondary);
  padding: 24px;
}

.pdf-viewer__toolbar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 6px 8px;
  background: var(--color-surface-variant);
  flex: 0 0 auto;
  flex-wrap: wrap;
}

.pdf-viewer__page-input {
  width: 56px;
  text-align: center;
  padding: 6px;
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-small);
  background: var(--color-surface);
  color: var(--color-on-surface);
}

.pdf-viewer__page-count {
  color: var(--color-on-surface-variant);
  margin: 0 12px 0 4px;
}

.pdf-viewer__zoom-group {
  display: flex;
  margin-left: 12px;
}

/* ---------- Exploded view detail ---------- */

.exploded-detail {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.exploded-detail__drawing {
  width: 100%;
  aspect-ratio: var(--drawing-aspect-ratio, 21 / 30);
  background: var(--color-secondary);
  overflow: hidden;
  position: relative;
  touch-action: none;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.exploded-detail__drawing img {
  max-width: 100%;
  max-height: 100%;
  transform-origin: center center;
  pointer-events: none;
  user-select: none;
}

.exploded-detail__drawing-empty {
  color: var(--color-on-secondary);
  padding: 24px;
}

.exploded-detail__body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.exploded-detail__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 16px;
}

.exploded-detail__title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.exploded-detail__page-select {
  flex: 0 0 auto;
  padding: 6px 8px;
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-small);
  background: var(--color-surface);
  color: var(--color-on-surface);
  font-size: 0.85rem;
}

.exploded-detail__filter {
  padding: 8px 16px;
}

/* Horizontal scroll wrapper for the header+rows pair: four columns don't fit
   a phone-width screen without cramming, so the row content gets a fixed
   min-width and scrolls sideways as one unit (header and rows are both
   direct children of this single scrolling box, so they always stay
   column-aligned - no separate scroll position to keep in sync). Not
   pretty, but showing which injector part number(s) each row belongs to
   matters more: an unlabelled row picked wrong under an "All" filter is
   REDAT's mistake, not the customer's. */
.exploded-detail__table-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-x: auto;
  display: flex;
  flex-direction: column;
}

.exploded-detail__table-scroll > .exploded-row-header,
.exploded-detail__table-scroll > .exploded-detail__rows {
  min-width: 640px;
}

.exploded-detail__rows {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.exploded-row-header,
.exploded-row {
  display: flex;
  padding: 10px 16px;
  border-bottom: 1px solid var(--color-outline);
  gap: 8px;
}

.exploded-row-header {
  padding: 6px 16px;
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
  font-weight: 600;
}

.col-pos {
  flex: 0 0 12%;
}

.col-part {
  flex: 0 0 25%;
}

.col-desc {
  flex: 1 1 33%;
}

.col-injector {
  flex: 0 0 30%;
}

/* Landscape: a fit-to-width drawing on top would leave almost no room for
   the filter+grid below it (worse than the catalog viewer's equivalent
   problem, see CLAUDE.md - there fit-to-height at least keeps the page
   readable; here the drawing would fill the screen and push the parts list
   out entirely). Side by side instead: drawing on the left sized to the
   available height (aspect-ratio switched off, so it's purely
   height-driven instead of width-driven - see the --drawing-aspect-ratio
   custom property above and screens/explodedDetail.js), filter+grid on the
   right getting its own full-height scroll region as before. */
@media (orientation: landscape) {
  .exploded-detail {
    flex-direction: row;
  }

  .exploded-detail__drawing {
    width: auto;
    height: 100%;
    aspect-ratio: auto;
    flex: 1 1 45%;
  }

  .exploded-detail__body {
    flex: 1 1 55%;
    min-width: 0;
    height: 100%;
  }
}

/* ---------- Search results ---------- */

.search-result {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  margin: 6px 0;
}

.search-result__thumb {
  flex: 0 0 auto;
}

.search-result__body {
  flex: 1 1 auto;
  min-width: 0;
}

.chip {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--color-outline);
  font-size: 0.75rem;
  margin-bottom: 8px;
}

.search-result__code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 1.05rem;
  margin: 0 0 4px;
}

.search-result__description {
  margin: 0 0 4px;
}

.search-result__location {
  color: var(--color-on-surface-variant);
  margin: 0;
  font-size: 0.85rem;
}

/* ---------- Buttons (filled + danger-outlined) ---------- */

.button {
  padding: 10px 16px;
  border: none;
  border-radius: var(--shape-small);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: 600;
  cursor: pointer;
  flex: 1 1 0;
}

.button:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Clearly grey (not just a dimmed red) while there's nothing to save -
   scoped to this one button so the notepad panel's dimmed-disabled buttons
   (Save/Send to REDAT/Clear all, disabled for a different reason - an empty
   notepad, not "no unsaved changes") keep their existing look. */
.settings-save-button:disabled {
  background: var(--color-surface-variant);
  color: var(--color-on-surface-variant);
  opacity: 1;
}

.button--danger {
  background: transparent;
  border: 1px solid var(--color-error);
  color: var(--color-error);
  width: 100%;
  margin-top: 8px;
}

/* Secondary action, same shape as .button but outlined - used by "Force
   full refresh" (screens/offlineData.js) next to the primary "Download
   updates" button. */
.button--outline {
  background: transparent;
  border: 1px solid var(--color-outline);
  color: var(--color-on-surface);
}

/* ---------- Installation and offline data ---------- */

/* One-line install status + action (screens/offlineData.js) - a second,
   always-reachable entry point into the same install flow as the global
   banner (components/installBanner.js), for anyone who already dismissed
   that one. */
.install-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 4px 0 12px;
}

.install-status__text {
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-on-surface-variant);
}

.offline-actions {
  display: flex;
  gap: 8px;
  margin: 16px 0 8px;
}

.offline-actions .button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.offline-actions__size {
  font-size: 0.78rem;
  font-weight: 400;
  opacity: 0.85;
}

.offline-progress {
  color: var(--color-on-surface-variant);
  margin-top: 8px;
}

.offline-banner {
  background: var(--color-surface-variant);
  border-radius: var(--shape-small);
  padding: 10px 12px;
  margin: 8px 0;
  color: var(--color-on-surface-variant);
  font-size: 0.9rem;
}

/* Scrolls within its own box instead of growing the whole page - a real
   catalog list can run into the dozens/hundreds, and the download/clear
   actions above must stay reachable without hunting for them below a long
   table (a real complaint from the user about the previous count-only
   summary, which at least never grew unbounded like this table can). */
.offline-table-wrap {
  max-height: 50vh;
  overflow-y: auto;
  overflow-x: auto;
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-small);
  margin-top: 8px;
}

/* min-width forces horizontal scroll on narrow phones instead of letting the
   nowrap status column overflow and get clipped under the fixed notepad tab
   (same tradeoff already accepted for the exploded-view parts grid). */
.offline-table {
  width: 100%;
  min-width: 480px;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.offline-table th {
  position: sticky;
  top: 0;
  background: var(--color-surface-variant);
  text-align: left;
  padding: 8px 10px;
  z-index: 1;
}

.offline-table td {
  padding: 8px 10px;
  border-top: 1px solid var(--color-outline);
  white-space: nowrap;
}

.offline-table td:first-child {
  white-space: normal;
}

.offline-table__row--outdated td:last-child,
.offline-table__row--missing td:last-child {
  color: var(--color-primary);
}

.offline-table__row--removed td:last-child,
.offline-table__row--offline td:last-child {
  color: var(--color-on-surface-variant);
  font-style: italic;
}

.offline-clear-cache {
  display: block;
  margin: 24px auto 0;
  color: var(--color-on-surface-variant);
  text-decoration: underline;
  font-weight: 400;
}

/* ---------- Persistent notepad panel ---------- */

.notepad-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 39;
}

.notepad-tab {
  position: fixed;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  width: 28px;
  height: 88px;
  border: none;
  border-radius: var(--shape-medium) 0 0 var(--shape-medium);
  background: var(--color-primary);
  color: var(--color-on-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 38;
  box-shadow: -1px 0 6px rgba(0, 0, 0, 0.2);
  /* Draggable up/down (see setupTabDrag() in notepadPanel.js) - none of
     the browser's own touch gestures make sense on the tab itself. */
  touch-action: none;
}

.notepad-tab__icon {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

/* Drag demo caption (components/notepadPanel.js's playTabDragDemo()) - a
   child of the tab button itself, not an independently-positioned element,
   so it rides along with the tab's own animated transform for free. */
.notepad-tab-caption {
  position: absolute;
  right: 100%;
  top: 50%;
  transform: translateY(-50%);
  margin-right: 8px;
  background: var(--color-on-background);
  color: var(--color-background);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: 6px;
  white-space: nowrap;
  pointer-events: none;
}

.notepad-panel {
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  width: min(300px, 85vw);
  background: var(--color-surface);
  transform: translateX(100%);
  transition: transform 0.2s ease;
  z-index: 40;
  display: flex;
  flex-direction: column;
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.15);
}

.notepad-panel--open {
  transform: translateX(0);
}

.notepad-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  border-bottom: 1px solid var(--color-outline);
  flex: 0 0 auto;
}

.notepad-panel__title {
  font-size: 1.2rem;
  margin: 0;
}

.notepad-panel__column-header {
  display: flex;
  padding: 6px 16px;
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
  font-weight: 600;
  flex: 0 0 auto;
}

.notepad-col-part {
  flex: 0 0 65%;
}

.notepad-col-qty {
  flex: 0 0 35%;
}

.notepad-panel__rows {
  flex: 1 1 auto;
  overflow-y: auto;
}

.notepad-row {
  display: flex;
  gap: 4px;
  padding: 4px 16px;
}

.notepad-row__part,
.notepad-row__qty {
  padding: 8px 10px;
  border: 1px solid var(--color-outline);
  border-radius: var(--shape-small);
  background: var(--color-surface);
  color: var(--color-on-surface);
  font-size: 0.9rem;
  min-width: 0;
}

.notepad-row__part {
  flex: 0 0 65%;
}

.notepad-row__qty {
  flex: 0 0 35%;
}

.notepad-panel__footer {
  flex: 0 0 auto;
  padding: 16px;
  border-top: 1px solid var(--color-outline);
}

.notepad-panel__footer-row {
  display: flex;
  gap: 8px;
}

/* ---------- Toast ---------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translate(-50%, 12px);
  background: var(--color-secondary);
  color: var(--color-on-secondary);
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 0.88rem;
  opacity: 0;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 50;
  max-width: min(90vw, 400px);
  text-align: center;
  pointer-events: none;
}

.toast--visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ---------- Contextual onboarding: spotlight coach mark ---------- */
/* components/spotlightHint.js - z-index 100/101 puts this above every fixed
   layer in the app, including the notepad panel (40), since the notepad
   intro hint targets buttons inside that panel while it's open. */

.spotlight-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: transparent;
}

/* The dim comes entirely from this element's own box-shadow spread (9999px,
   far past any viewport) rather than from .spotlight-backdrop - a
   transparent box whose shadow covers everything else creates a "cut out"
   around the real target, letting it show through undimmed at its true
   position, whatever that target's own DOM nesting/stacking context is
   (see the module docstring for why that matters for the notepad panel). */
.spotlight-ring {
  position: fixed;
  z-index: 100;
  box-shadow:
    0 0 0 9999px rgba(10, 12, 14, 0.6),
    0 0 0 3px var(--redat-red),
    0 8px 22px -8px rgba(196, 31, 58, 0.6);
  border-radius: var(--shape-small);
  pointer-events: none;
}

.spotlight-tip {
  position: fixed;
  z-index: 101;
  max-width: 280px;
  background: var(--color-surface);
  color: var(--color-on-surface);
  border-radius: var(--shape-medium);
  padding: 14px 16px;
  box-shadow: 0 10px 28px -8px rgba(0, 0, 0, 0.4);
}

.spotlight-tip::before {
  content: "";
  position: absolute;
  left: var(--spotlight-arrow-left, 24px);
  width: 12px;
  height: 12px;
  background: var(--color-surface);
  transform: translateX(-50%) rotate(45deg);
}

.spotlight-tip--below::before {
  top: -6px;
}

.spotlight-tip--above::before {
  bottom: -6px;
}

.spotlight-tip__message {
  margin: 0 0 12px;
  font-size: 0.92rem;
  line-height: 1.45;
}

.spotlight-tip__action {
  font: inherit;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--redat-red);
  background: none;
  border: none;
  padding: 4px 2px;
  cursor: pointer;
}

/* ---------- Contextual onboarding: lightweight badge ---------- */
/* components/lightBadge.js */

.light-badge {
  position: fixed;
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--color-secondary);
  color: var(--color-on-secondary);
  font-size: 0.95rem;
  font-weight: 700;
  padding: 12px 20px;
  border-radius: 999px;
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  max-width: min(85vw, 320px);
  text-align: center;
}

.light-badge__dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--redat-red);
  flex: 0 0 auto;
  animation: light-badge-pulse 1.6s ease-in-out infinite;
}

@keyframes light-badge-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(196, 31, 58, 0.55); }
  50% { box-shadow: 0 0 0 7px rgba(196, 31, 58, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .light-badge__dot { animation: none; }
}
