/* ========================================================================
   Notification Center - Centralized status & progress system
   ===================================================================== */

/* Notifications share the bottom edge with the selection bar and stack above
   it while it is shown (select-bar-placement.js publishes its height). */
.notification-center {
  position: fixed;
  bottom: calc(var(--space-4) + var(--select-bar-block-size, 0px));
  right: var(--space-4);
  z-index: var(--z-notification);
  display: flex;
  flex-direction: column-reverse;
  gap: var(--space-2);
  pointer-events: none;
  max-width: 360px;
  max-height: calc(100vh - var(--space-8));
  overflow: hidden;
  /* GPU acceleration for smooth animations */
  transform: translateZ(0);
  will-change: contents;
}

/* The welcome dialog is the one thing to act on at first start. On a short
   screen it fills the height, so startup notifications landed on its buttons;
   there they wait beneath it and are seen once it closes. */
@media (max-height: 500px) {
  body:has(#welcome-modal:not(.hidden)) .notification-center {
    z-index: calc(var(--z-modal) - 1);
  }

  /* A short screen (a phone on its side) holds two cards. The stack is
     clipped at its top, where the newest card sits, so the older cards step
     aside instead of the newest being cut off. They were announced when
     they arrived. */
  .notification-center > .notification:not(:nth-last-child(-n + 2)) {
    display: none;
  }
}

/* Individual notification - newspaper-inspired card */
.notification {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2-5) var(--space-3);
  /* Paper-like background with subtle transparency */
  background: var(--color-surface-elevated);
  background: color-mix(in srgb, var(--color-surface-elevated) 95%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: var(--border-default);
  border-radius: var(--radius-none);
  box-shadow: var(--shadow-md);
  font-family: var(--font-sans);
  font-size: var(--type-body);
  color: var(--color-text-primary);
  pointer-events: auto;
  min-width: 240px;
  max-width: 360px;
  /* GPU-accelerated animation properties */
  transform: translateX(100%) translateZ(0);
  opacity: 0;
  transition: transform var(--duration-normal) var(--easing-smooth),
    opacity var(--duration-normal) var(--easing-smooth);
  will-change: transform, opacity;
}

.notification-enter {
  transform: translateX(0) translateZ(0);
  opacity: 1;
}

.notification-exit {
  transform: translateX(100%) translateZ(0);
  opacity: 0;
}

/* Notification icon */
.notification-icon {
  flex-shrink: 0;
  width: var(--space-5);
  height: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--control-glyph-md);
  color: var(--color-text-secondary);
}

/* Type-specific icon colors - all use ink colors for newspaper consistency */
.notification-success .notification-icon,
.notification-error .notification-icon,
.notification-warning .notification-icon,
.notification-loading .notification-icon,
.notification-progress .notification-icon {
  color: var(--color-text-primary);
}

/* Notification content */
.notification-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--control-row-gap);
}

.notification-title {
  font-size: var(--type-label);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  color: var(--color-text-secondary);
}

.notification-message {
  font-size: var(--type-body);
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
  word-break: break-word;
  /* Messages are written as several sentences, and two are a key/value list
     built with `bits.join('\n')`. The escaping on the way in leaves `\n`
     alone, so the break arrives here intact; without this it is folded into a
     space and the sentences run together. `pre-line` honours the break and
     still collapses the ordinary whitespace of concatenated source. */
  white-space: pre-line;
}

/* The technical text behind a short message (a failure's raw error), folded. */
.notification-details {
  font-size: var(--type-hint);
  line-height: var(--leading-normal);
  color: var(--color-text-secondary);
}

.notification-details > summary {
  cursor: pointer;
  width: fit-content;
}

.notification-details-text {
  margin-top: var(--space-0-5);
  word-break: break-word;
  white-space: pre-line;
}

/* A notification's one follow-up action, under its message. */
.notification-action,
.notification-cancel {
  align-self: flex-start;
}

/* Type-specific styles - newspaper-inspired visual distinction */
/* Uses ink weight variations instead of colors */
.notification-success {
  border-left: 3px solid var(--color-text-primary); /* Bold ink - complete */
}

.notification-error {
  border-left: 3px double var(--color-text-primary); /* Double line - attention needed */
}

.notification-warning {
  border-left: 3px dashed var(--color-text-secondary); /* Dashed - caution */
}

.notification-loading,
.notification-progress {
  border-left: 3px solid var(--color-text-tertiary); /* Muted - in progress */
}

/* Progress bar container */
.notification-progress-container {
  width: 100%;
  height: var(--space-1);
  background: var(--color-border-light);
  border-radius: var(--radius-sm);
  overflow: hidden;
  margin-top: var(--space-0-5);
}

/* Progress bar fill */
.notification-progress-bar {
  height: 100%;
  background: var(--color-text-primary);
  border-radius: var(--radius-sm);
  transition: width var(--duration-fast) var(--easing-out);
  /* GPU acceleration */
  transform: translateZ(0);
  will-change: width;
}

/* Indeterminate animation */
.notification-progress-bar.indeterminate {
  width: 30% !important;
  animation: progress-indeterminate 1.2s ease-in-out infinite;
}

@keyframes progress-indeterminate {
  0% {
    transform: translateX(-100%) translateZ(0);
  }
  50% {
    transform: translateX(233%) translateZ(0);
  }
  100% {
    transform: translateX(-100%) translateZ(0);
  }
}

/* Progress text and speed */
.notification-progress-text,
.notification-speed {
  font-variant-numeric: tabular-nums;
  font-size: var(--type-readout);
  color: var(--color-text-secondary);
}

.notification-speed {
  color: var(--color-text-secondary);
}

/* Dismiss button */
.notification-dismiss {
  flex-shrink: 0;
  position: relative;
  width: var(--space-5);
  height: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  font-size: var(--control-glyph-lg);
  line-height: var(--leading-none);
  /* Secondary, not tertiary: the card is translucent, and over a light plot
     tertiary ink dropped under 4.5:1. */
  color: var(--color-text-secondary);
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: color var(--duration-fast) var(--easing-standard),
    background-color var(--duration-fast) var(--easing-standard);
  margin: calc(-1 * var(--space-0-5)) calc(-1 * var(--space-1)) 0 0;
  padding: 0;
}

.notification-dismiss:hover {
  color: var(--color-text-primary);
  background: color-mix(in srgb, var(--color-text-primary) 5%, transparent);
}

.notification-dismiss:active {
  background: color-mix(in srgb, var(--color-text-primary) 10%, transparent);
}

/* Loading spinner animation for icon (the shared `spin` turn). */
.notification-loading .notification-icon {
  animation: spin var(--duration-spin) linear infinite;
}

/* On a touch screen, and in the phone layout where the menu fills the screen,
   a card's body lets the pointer through to what lies beneath it, so a swipe
   that starts on a card still scrolls the sidebar menu and the controls under
   a card stay reachable: the cards span the width of a phone where a thumb
   swipes. Only its buttons take the press. Elsewhere a mouse keeps the card
   itself, so its text can still be selected and copied. */
@media (pointer: coarse), (max-width: 720px) {
  .notification {
    pointer-events: none;
  }

  .notification button {
    pointer-events: auto;
  }
}

/* Responsive adjustments */
@media (max-width: 480px) {
  .notification-center {
    left: var(--space-2);
    right: var(--space-2);
    bottom: calc(var(--space-2) + var(--select-bar-block-size, 0px));
    max-width: none;
  }

  .notification {
    min-width: 0;
    max-width: none;
  }
}

/* Messages retired early to keep the stack at five cards: a control under the
   stack names how many, and opens the list of every one of them. */
.notification-overflow {
  pointer-events: auto;
  min-width: 240px;
  max-width: 360px;
  background: var(--color-surface-elevated);
  border: var(--border-default);
  box-shadow: var(--shadow-md);
  font-family: var(--font-sans);
  font-size: var(--type-label);
}

.notification-overflow-bar {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-1-5) var(--space-2);
}

.notification-overflow-list {
  max-height: 40vh;
  overflow-y: auto;
  border-top: var(--border-light);
}

.notification-overflow-list[hidden] {
  display: none;
}

.notification-overflow-item {
  padding: var(--space-1-5) var(--space-2);
  border-bottom: var(--border-light);
  overflow-wrap: anywhere;
}

.notification-overflow-item:last-child {
  border-bottom: none;
}
