/**
 * @file saveToCloud.css
 * @description Styles for the "Save to Cloud" modal dialog in School Draw —
 *              used for saving drawings to both Google Drive and OneDrive.
 *              Loaded dynamically by authGatedLoader.js after authentication.
 *
 * CONTENTS
 * --------
 * 1. Modal containers (.stgd-modal, .stod-modal)
 *    Shared full-screen modal overlay for Google Drive (.stgd-*) and
 *    OneDrive (.stod-*) save dialogs respectively.
 *    Gain .stgd-active / .stod-active class to become visible.
 *
 * 2. Backdrop (.stgd-backdrop, .stod-backdrop)
 *    Semi-transparent dark overlay behind the modal card.
 *    Click-to-close area.
 *
 * 3. Modal card (.stgd-dialog, .stod-dialog)
 *    Centred white card with rounded corners and drop shadow.
 *    Slide-up + fade-in animation on open; slides down on close.
 *    max-width: 480px, responsive on small screens.
 *
 * 4. Header (.stgd-header, .stod-header)
 *    Provider icon (Google / Microsoft logo SVG), dialog title ("Save to
 *    Google Drive" / "Save to OneDrive"), close button (×).
 *
 * 5. File name input (.stgd-filename, .stod-filename)
 *    Text field for the drawing file name.  Validates against filesystem-safe
 *    character rules (enforced in saveToCloud.js).  Error state styling
 *    (.stgd-filename.error) shows red border and shake animation.
 *
 * 6. Folder / location display (.stgd-folder, .stod-folder)
 *    Read-only indicator showing the destination folder ("MyDrawings" /
 *    "SVGEditor") with a folder icon.
 *
 * 7. Action buttons (.stgd-actions, .stod-actions)
 *    Cancel and Save buttons.  Save button shows a spinner while the
 *    upload is in progress.
 *
 * 8. Progress indicator (.stgd-progress, .stod-progress)
 *    Thin progress bar animated across the top of the dialog card during
 *    the upload, using CSS animation with indeterminate width.
 *
 * 9. Status / error messages (.stgd-status, .stod-status)
 *    Inline feedback area below the file name input showing success or
 *    error messages with colour-coded icons.
 *
 * 10. Shared save button spinner (.stgd-save-spinner, .stod-save-spinner)
 *     Small CSS spinner inside the Save button during upload.
 *
 * 11. Responsive overrides
 *     @media (max-width: 480px) — dialog fills most of screen width.
 *
 * RELATED JS FILE
 * ---------------
 * saveToCloud.js   — CloudSaveManager class; drives modal open/close,
 *                    filename validation, and Drive/OneDrive API calls.
 * gAuth.js         — provides window.googleDriveAPI.saveFile().
 * msAuth.js        — provides window.msOneDriveAPI.saveFile().
 */
.stgd-modal,
.stod-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
}
.stgd-active,
.stod-active {
  opacity: 1;
  pointer-events: auto;
}
.stgd-backdrop,
.stod-backdrop {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgb(0 0 0 / 0.5);
  backdrop-filter: blur(4px);
}
.stgd-cloud {
  position: absolute;
  opacity: 0.3;
  animation: float 20s ease-in-out infinite;
}
.stgd-cloud-1 {
  top: 10%;
  left: 10%;
  animation-delay: 0s;
}
.stgd-cloud-2 {
  bottom: 20%;
  right: 15%;
  animation-delay: 5s;
}
@keyframes float {
  0%,
  100% {
    transform: translateY(0) translateX(0);
  }
  25% {
    transform: translateY(-20px) translateX(10px);
  }
  50% {
    transform: translateY(0) translateX(20px);
  }
  75% {
    transform: translateY(20px) translateX(10px);
  }
}
.stod-square {
  position: absolute;
  width: 40px;
  height: 40px;
  opacity: 0.2;
  animation: rotate-square 15s linear infinite;
}
.stod-square-1 {
  top: 10%;
  left: 10%;
  background: #f25022;
}
.stod-square-2 {
  top: 10%;
  right: 10%;
  background: #7fba00;
  animation-delay: 3s;
}
.stod-square-3 {
  bottom: 10%;
  left: 10%;
  background: #00a4ef;
  animation-delay: 6s;
}
.stod-square-4 {
  bottom: 10%;
  right: 10%;
  background: #ffb900;
  animation-delay: 9s;
}
@keyframes rotate-square {
  0%,
  100% {
    transform: rotate(0) scale(1);
  }
  25% {
    transform: rotate(90deg) scale(1.2);
  }
  50% {
    transform: rotate(180deg) scale(1);
  }
  75% {
    transform: rotate(270deg) scale(0.8);
  }
}
.stgd-container,
.stod-container {
  position: relative;
  background: #fff;
  border-radius: 24px;
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.3);
  max-width: 500px;
  width: 90%;
  max-height: 90vh;
  overflow: hidden;
  transform: translateY(20px);
  transition: transform 0.3s ease;
  display: flex;
  flex-direction: column;
}
.stgd-active .stgd-container,
.stod-active .stod-container {
  transform: translateY(0);
}
.stgd-close,
.stod-close {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.9);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  z-index: 10;
}
.stgd-close:hover,
.stod-close:hover {
  background: #fff;
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.15);
  transform: scale(1.1);
}
.stgd-close svg,
.stod-close svg {
  width: 20px;
  height: 20px;
  stroke: #6b7280;
}
.stgd-header {
  background: linear-gradient(135deg, #4285f4 0, #34a853 100%);
  padding: 40px 30px 30px;
  text-align: center;
  color: #fff;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}
.stod-header {
  background: linear-gradient(135deg, #0078d4 0, #107c10 100%);
  padding: 40px 30px 30px;
  text-align: center;
  color: #fff;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}
.stgd-header-icon,
.stod-header-icon {
  width: 80px;
  height: 80px;
  margin: 0 auto 20px;
  background: rgb(255 255 255 / 0.2);
  border-radius: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(10px);
  position: relative;
}
.stgd-cloud-icon,
.stod-cloud-icon {
  width: 50px;
  height: 50px;
}
.stgd-google-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  width: 32px;
  height: 32px;
  background: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.15);
}
.stod-ms-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  width: 32px;
  height: 32px;
  background: #fff;
  border-radius: 4px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 2px;
  padding: 4px;
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.15);
}
.stod-ms-square:first-child {
  background: #f25022;
}
.stod-ms-square:nth-child(2) {
  background: #7fba00;
}
.stod-ms-square:nth-child(3) {
  background: #00a4ef;
}
.stod-ms-square:nth-child(4) {
  background: #ffb900;
}
.stgd-title,
.stod-title {
  font-size: 28px;
  font-weight: 700;
  margin: 0 0 10px 0;
  letter-spacing: -0.5px;
}
.stgd-subtitle,
.stod-subtitle {
  font-size: 16px;
  opacity: 0.95;
  margin: 0;
  font-weight: 500;
}
.stgd-body,
.stod-body {
  padding: 30px;
  background: #fff;
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}
.stgd-body::-webkit-scrollbar,
.stod-body::-webkit-scrollbar {
  width: 8px;
}
.stgd-body::-webkit-scrollbar-track,
.stod-body::-webkit-scrollbar-track {
  background: #f3f4f6;
  border-radius: 4px;
}
.stgd-body::-webkit-scrollbar-thumb,
.stod-body::-webkit-scrollbar-thumb {
  background: #d1d5db;
  border-radius: 4px;
}
.stgd-body::-webkit-scrollbar-thumb:hover,
.stod-body::-webkit-scrollbar-thumb:hover {
  background: #9ca3af;
}
.stgd-auth-status,
.stod-auth-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: linear-gradient(135deg, #f0fdf4 0, #dcfce7 100%);
  border: 2px solid #86efac;
  border-radius: 12px;
  margin-bottom: 24px;
}
.stgd-not-signed-in,
.stod-not-signed-in {
  background: linear-gradient(135deg, #fffbeb 0, #fef3c7 100%);
  border-color: #fcd34d;
}
.stgd-auth-icon,
.stod-auth-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.stgd-auth-icon svg,
.stod-auth-icon svg {
  width: 24px;
  height: 24px;
}
.stgd-auth-text,
.stod-auth-text {
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: #166534;
}
.stgd-not-signed-in .stgd-auth-text,
.stod-not-signed-in .stod-auth-text {
  color: #92400e;
}
.stgd-auth-user,
.stod-auth-user {
  font-weight: 700;
  color: #065f46;
}
.stgd-signin-btn,
.stod-signin-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: #fff;
  border: 2px solid #e5e7eb;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #374151;
}
.stgd-signin-btn:hover,
.stod-signin-btn:hover {
  border-color: #9ca3af;
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.1);
  transform: translateY(-1px);
}
.stgd-step-header,
.stod-step-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.stgd-step-title,
.stod-step-title {
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}
.stgd-name-input,
.stod-name-input {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid #e5e7eb;
  border-radius: 12px;
  font-size: 16px;
  font-family: inherit;
  transition: all 0.2s ease;
  background: #fff;
}
.stgd-name-input:focus,
.stod-name-input:focus {
  outline: 0;
  border-color: #4285f4;
  box-shadow: 0 0 0 3px rgb(66 133 244 / 0.1);
}
.stod-name-input:focus {
  border-color: #0078d4;
  box-shadow: 0 0 0 3px rgb(0 120 212 / 0.1);
}
.stgd-name-input::placeholder,
.stod-name-input::placeholder {
  color: #9ca3af;
}
.stgd-folder-info,
.stod-folder-info {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  margin-bottom: 24px;
}
.stgd-folder-text,
.stod-folder-text {
  font-size: 13px;
  color: #6b7280;
  line-height: 1.5;
}
.stgd-folder-text strong,
.stod-folder-text strong {
  color: #1f2937;
  font-weight: 600;
}
.stgd-actions,
.stod-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}
.stgd-btn,
.stod-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  border: none;
  font-family: inherit;
}
.stgd-btn-cancel,
.stod-btn-cancel {
  background: #f3f4f6;
  color: #6b7280;
}
.stgd-btn-cancel:hover,
.stod-btn-cancel:hover {
  background: #e5e7eb;
  transform: translateY(-1px);
}
.stgd-btn-save {
  background: linear-gradient(135deg, #4285f4 0, #34a853 100%);
  color: #fff;
}
.stod-btn-save {
  background: linear-gradient(135deg, #0078d4 0, #107c10 100%);
  color: #fff;
}
.stgd-btn-save:hover,
.stod-btn-save:hover {
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.2);
  transform: translateY(-2px);
}
.stgd-loading,
.stod-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgb(255 255 255 / 0.95);
  backdrop-filter: blur(4px);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  z-index: 20;
}
.stgd-show,
.stod-show {
  display: flex !important;
}
.stgd-spinner,
.stod-spinner {
  width: 60px;
  height: 60px;
  position: relative;
}
.stgd-spinner-ring {
  width: 100%;
  height: 100%;
  border: 4px solid #e5e7eb;
  border-top-color: #4285f4;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
.stod-spinner-squares {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 4px;
}
.stod-spinner-square:first-child {
  background: #f25022;
}
.stod-spinner-square:nth-child(2) {
  background: #7fba00;
}
.stod-spinner-square:nth-child(3) {
  background: #00a4ef;
}
.stod-spinner-square:nth-child(4) {
  background: #ffb900;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
.stgd-success-overlay,
.stod-success-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgb(255 255 255 / 0.98);
  backdrop-filter: blur(8px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 30;
}
.stgd-success-content,
.stod-success-content {
  text-align: center;
  padding: 40px;
  max-width: 400px;
}
.stgd-success-title,
.stod-success-title {
  font-size: 24px;
  font-weight: 700;
  color: #1f2937;
  margin: 0 0 12px 0;
}
.stgd-success-message,
.stod-success-message {
  font-size: 16px;
  color: #6b7280;
  margin: 0 0 24px 0;
  line-height: 1.5;
}
.stgd-error-toast,
.stod-error-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(100px);
  background: #fff;
  padding: 16px 20px;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.15);
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 10001;
  max-width: 400px;
  border: 2px solid #fca5a5;
  opacity: 0;
  transition: all 0.3s ease;
}
.stgd-error-toast.stgd-show,
.stod-error-toast.stod-show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}
.stgd-error-toast svg,
.stod-error-toast svg {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  fill: #dc2626;
}
.stgd-error-toast span,
.stod-error-toast span {
  font-size: 14px;
  font-weight: 500;
  color: #1f2937;
  flex: 1;
}
@media (max-width: 640px) {
  .stgd-container,
  .stod-container {
    width: 95%;
    max-height: 95vh;
    margin: 10px;
  }
  .stgd-header,
  .stod-header {
    padding: 30px 20px 20px;
  }
  .stgd-title,
  .stod-title {
    font-size: 24px;
  }
  .stgd-subtitle,
  .stod-subtitle {
    font-size: 14px;
  }
  .stgd-body,
  .stod-body {
    padding: 20px;
  }
  .stgd-actions,
  .stod-actions {
    flex-direction: column;
  }
  .stgd-btn,
  .stod-btn {
    width: 100%;
    justify-content: center;
  }
  .stgd-error-toast,
  .stod-error-toast {
    max-width: 90%;
    left: 5%;
    transform: translateX(0) translateY(100px);
  }
  .stgd-error-toast.stgd-show,
  .stod-error-toast.stod-show {
    transform: translateX(0) translateY(0);
  }
}
@media (max-height: 700px) {
  .stgd-header,
  .stod-header {
    padding: 30px 25px 20px;
  }
  .stgd-header-icon,
  .stod-header-icon {
    width: 60px;
    height: 60px;
    margin-bottom: 15px;
  }
  .stgd-cloud-icon,
  .stod-cloud-icon {
    width: 40px;
    height: 40px;
  }
  .stgd-title,
  .stod-title {
    font-size: 24px;
  }
  .stgd-subtitle,
  .stod-subtitle {
    font-size: 14px;
  }
  .stgd-body,
  .stod-body {
    padding: 20px;
  }
}
.stgd-btn:focus,
.stgd-close:focus,
.stgd-name-input:focus,
.stod-btn:focus,
.stod-close:focus,
.stod-name-input:focus {
  outline: 2px solid #4285f4;
  outline-offset: 2px;
}
.stod-btn:focus,
.stod-close:focus,
.stod-name-input:focus {
  outline-color: #0078d4;
}
@media (prefers-contrast: high) {
  .stgd-container,
  .stod-container {
    border: 2px solid currentColor;
  }
  .stgd-name-input,
  .stod-name-input {
    border-width: 3px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .stgd-btn,
  .stgd-container,
  .stgd-error-toast,
  .stgd-modal,
  .stod-btn,
  .stod-container,
  .stod-error-toast,
  .stod-modal {
    transition: none;
    animation: none;
  }
  .stgd-cloud,
  .stgd-confetti,
  .stgd-emoji-float,
  .stgd-spinner-ring,
  .stod-confetti,
  .stod-icon-float,
  .stod-spinner-square,
  .stod-square {
    animation: none;
  }
}
@keyframes qs-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes qs-fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@keyframes qs-slide-in-right {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes qs-slide-out-right {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(100%);
    opacity: 0;
  }
}
@keyframes qs-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}
#btnSave.modified {
  position: relative;
}
#btnSave.modified::before {
  content: "●";
  position: absolute;
  top: 4px;
  right: 4px;
  color: #ef4444;
  font-size: 12px;
  animation: qs-pulse 2s ease infinite;
}
.quick-save-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  padding: 12px 20px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  color: #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 10002;
  animation: qs-slide-in-right 0.3s ease;
  max-width: 360px;
}
.quick-save-toast.toast-success {
  background: #0f6b4f;
}
.quick-save-toast.toast-error {
  background: #b3261e;
}
.quick-save-toast.toast-info {
  background: #1d4ed8;
}
.quick-save-toast.toast-out {
  animation: qs-slide-out-right 0.3s ease forwards;
}
.qs-device-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  animation: qs-fade-in 0.2s ease;
}
.qs-device-modal.qs-fade-out {
  animation: qs-fade-out 0.2s ease forwards;
}
.qs-card {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  width: min(500px, 92vw);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.qs-card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.qs-card-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  color: #fff;
  background: linear-gradient(135deg, #713b00 0, #d97706 100%);
}
.qs-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #111827;
}
.qs-subtitle {
  margin: 4px 0 0;
  font-size: 14px;
  color: #6b7280;
}
.qs-callout {
  background: #fef3c7;
  border: 1px solid #fcd34d;
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 16px;
}
.qs-callout-text {
  margin: 0;
  font-size: 14px;
  color: #92400e;
  line-height: 1.5;
}
.qs-meta {
  background: #f3f4f6;
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 20px;
}
.qs-meta-label {
  margin: 0 0 4px;
  font-size: 12px;
  color: #6b7280;
  font-weight: 500;
}
.qs-meta-value {
  margin: 0 0 12px;
  font-size: 14px;
  color: #1f2937;
  font-weight: 600;
  word-break: break-all;
}
.qs-meta-green {
  color: #059669;
}
.qs-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}
.qs-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  font-size: 14px;
  transition:
    transform 0.2s,
    box-shadow 0.2s;
}
.qs-cancel-btn {
  background: #e5e7eb;
  color: #374151;
}
.qs-cancel-btn:hover {
  background: #d1d5db;
}
.qs-download-btn {
  background: linear-gradient(135deg, #07543d 0, #064e3b 100%);
  color: #fff;
  box-shadow: 0 2px 4px rgba(16, 185, 129, 0.2);
}
.qs-download-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(16, 185, 129, 0.3);
}
@keyframes stl-spin {
  to {
    transform: rotate(360deg);
  }
}
.vh-toolbar-btn {
  padding: 8px 16px;
  font-size: 24px;
  border: 1px solid #ddd;
  background: #fff;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
}
.vh-toolbar-btn:hover {
  background: #f3f4f6;
  border-color: #3b82f6;
}
.vh-panel {
  position: fixed;
  top: 50%;
  right: -420px;
  transform: translateY(-50%);
  width: 400px;
  max-width: 90vw;
  max-height: 85vh;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  z-index: 10000;
  display: flex;
  flex-direction: column;
  transition: right 0.3s ease;
}
.vh-panel.show {
  right: 20px;
}
.vh-header {
  padding: 20px 20px 12px 20px;
  border-bottom: 1px solid #e5e7eb;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.vh-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}
.vh-close {
  background: 0 0;
  border: none;
  font-size: 28px;
  cursor: pointer;
  width: 40px;
  height: 40px;
  border-radius: 6px;
  color: #6b7280;
}
.vh-close:hover {
  background: #f3f4f6;
  color: #111827;
}
.vh-info {
  padding: 8px 20px 12px 20px;
  border-bottom: 1px solid #e5e7eb;
  background: #f9fafb;
}
.vh-info small {
  color: #6b7280;
  font-size: 12px;
}
.vh-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}
.vh-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.vh-empty {
  text-align: center;
  padding: 60px 20px;
  color: #9ca3af;
}
.vh-empty p {
  margin: 0 0 8px 0;
  font-size: 16px;
}
.vh-empty small {
  font-size: 13px;
}
.vh-item {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 14px;
  background: #fff;
  transition: all 0.2s;
}
.vh-item:hover {
  border-color: #3b82f6;
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
}
.vh-item-content {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}
.vh-thumbnail {
  flex-shrink: 0;
  width: 80px;
  height: 60px;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid #e5e7eb;
  background: #f9fafb;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vh-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.vh-item-details {
  flex: 1;
  min-width: 0;
}
.vh-item-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
.vh-item-number {
  font-weight: 600;
  color: #3b82f6;
  font-size: 13px;
}
.vh-item-time {
  font-size: 12px;
  color: #6b7280;
}
.vh-item-info {
  margin-bottom: 0;
}
.vh-item-filename {
  font-weight: 500;
  color: #111827;
  margin-bottom: 4px;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vh-item-meta {
  font-size: 12px;
  color: #9ca3af;
}
.vh-item-actions {
  display: flex;
  gap: 8px;
}
.vh-action-btn {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #e5e7eb;
  background: #fff;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.2s;
}
.vh-restore:hover {
  background: #1742b5;
  border-color: #1742b5;
  color: #fff;
}
.vh-delete:hover {
  background: #921b16;
  border-color: #921b16;
  color: #fff;
}
.vh-toast {
  position: fixed;
  bottom: -60px;
  left: 50%;
  transform: translateX(-50%);
  background: #111827;
  color: #fff;
  padding: 12px 24px;
  border-radius: 8px;
  font-size: 14px;
  z-index: 10001;
  transition: bottom 0.3s ease;
}
.vh-toast.show {
  bottom: 20px;
}
.vh-toast-error {
  background: #b3261e;
}
.vh-toast-warning {
  background: #8a4b00;
}

/* The .vh-confirm-* rules that stood here styled the version-history
   panel's own confirmation overlay. That overlay was removed on
   25 Aug 2026 when both apps moved to UnifiedModals.confirm, which
   is a native <dialog> styled by css/core/modals.css. Nothing
   referenced these rules afterwards, and they were still being
   downloaded and precached by every user. */


.vh-cancel {
  background: #f3f4f6;
  color: #374151;
}
.vh-ok {
  background: #1742b5;
  color: #fff;
}
@media (max-width: 768px) {
  .vh-panel {
    width: 90vw;
  }
  .vh-thumbnail {
    width: 60px;
    height: 45px;
  }
}
@keyframes spin {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE "OPEN DRAWING" PICKER  (openFromLocal.js)
   ══════════════════════════════════════════════════════════════════════════
   These rules style what is INSIDE the picker. The panel, the backdrop, the
   heading and the close button are the shared dialog's job now — see
   `css/core/modals.css` — so nothing here draws a card or a shell.

   ── WHY EVERY COLOUR IS A TOKEN ────────────────────────────────────────────
   This block used to be written in fixed light-mode colours: `#1f2937` text,
   `#6b7280` for the quieter lines, white on `#3b82f6` for the buttons. It got
   away with it because the picker drew its own white card, so the card and the
   text were wrong together and therefore looked right.

   The card is now the shared dialog, which follows the theme. Fixed dark text
   on a themed panel measured **1.07:1** in dark mode — text the same colour as
   what is behind it. The lesson is the same one the dialog's own buttons
   taught: if a rule sets one half of a foreground/background pair, it owns the
   other half too, or some other stylesheet will supply it and the two will not
   agree.

   So every colour here comes from the app's tokens, with a light-mode fallback
   for an app that has not defined them.

   ── WHY THE BUTTONS ARE NOT FILLED WITH A SOLID COLOUR ─────────────────────
   White on `#3b82f6` is 3.68:1 and white on `#ef4444` is 3.76:1. Both are
   below the 4.5:1 that AA asks of normal text, and both were failing here
   before this rewrite — in light mode as well as dark. Emphasis is carried by
   a tint, a border and weight instead, with the text staying `--ink` on
   `--panel`: the pairing every app has already had to get right.
   ══════════════════════════════════════════════════════════════════════════ */

.ofl-subtitle {
  margin: 0 0 1rem;
  color: var(--ink, #1f2937);
  font-size: var(--font-size-sm, 0.875rem);
}

/* ── The Saved Drawings / From Device toggle ────────────────────────────── */

.ofl-view-toggle {
  display: flex;
  gap: 8px;
  margin-bottom: 1rem;
}

.ofl-toggle-btn {
  flex: 1;
  min-height: var(--min-touch-target, 44px);
  padding: 12px 16px;
  font: inherit;
  font-weight: 500;
  color: var(--ink, #1f2937);
  background: var(--panel, #fff);
  border: 2px solid var(--line, #d1d5db);
  border-radius: var(--radius-sm, 8px);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.ofl-toggle-btn.active {
  font-weight: 700;
  border-color: var(--accent, #0f766e);
}

.ofl-toggle-btn:hover:not(.active) {
  border-color: var(--line-strong, #93a3b5);
}

/* ── The two panes ──────────────────────────────────────────────────────── */

.ofl-view {
  display: none;
}

.ofl-view.active {
  display: block;
}

.ofl-body {
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* ── How many, and in what order ────────────────────────────────────────── */

.ofl-status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 12px;
}

.ofl-count {
  color: var(--ink, #1f2937);
  font-size: var(--font-size-sm, 0.875rem);
}

.ofl-count-number {
  font-weight: 700;
  color: var(--ink, #1f2937);
}

.ofl-sort-controls {
  display: flex;
  gap: 8px;
}

.ofl-sort-btn {
  min-height: var(--min-touch-target, 44px);
  padding: 8px 14px;
  font: inherit;
  font-size: var(--font-size-sm, 0.875rem);
  color: var(--ink, #1f2937);
  background: var(--panel, #fff);
  border: 2px solid var(--line, #d1d5db);
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
}

.ofl-sort-btn.active {
  font-weight: 700;
  border-color: var(--accent, #0f766e);
}

/* ── One saved drawing ──────────────────────────────────────────────────── */

.ofl-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ofl-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 72px;
  padding: 16px;
  border: 1px solid var(--line, #e5e7eb);
  border-radius: var(--radius-sm, 8px);
}

.ofl-item:hover {
  border-color: var(--line-strong, #93a3b5);
}

.ofl-item-info {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  /* A very long name must not push the buttons off the panel. */
  min-width: 0;
}

.ofl-item-details {
  min-width: 0;
}

.ofl-item-name {
  margin: 0 0 4px;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink, #1f2937);
  /* Names come from children and can be long. Wrap rather than overflow. */
  overflow-wrap: anywhere;
}

.ofl-item-date {
  margin: 0;
  font-size: var(--font-size-sm, 0.875rem);
  color: var(--ink, #1f2937);
}

.ofl-item-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

/* ── The Open and Delete buttons ────────────────────────────────────────── */

.ofl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--min-touch-target, 44px);
  min-width: 44px;
  padding: 10px 18px;
  font: inherit;
  font-size: var(--font-size-sm, 0.875rem);
  font-weight: 600;
  color: var(--ink, #1f2937);
  background: var(--panel, #fff);
  border: 2px solid var(--line-strong, #93a3b5);
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
}

.ofl-btn-primary {
  font-weight: 700;
  border-color: var(--accent, #0f766e);
}

.ofl-btn-danger {
  font-weight: 700;
  border-color: var(--danger, #b3261e);
}

.ofl-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ── Nothing saved yet ──────────────────────────────────────────────────── */

.ofl-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  text-align: center;
}

.ofl-empty h3 {
  margin: 0 0 8px;
  color: var(--ink, #1f2937);
  font-size: 1.25rem;
}

.ofl-empty p {
  margin: 0;
  color: var(--ink, #1f2937);
}

/* ── Choosing a file from the device ────────────────────────────────────── */

.ofl-upload-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  border: 2px dashed var(--line, #d1d5db);
  border-radius: var(--radius, 12px);
  text-align: center;
}

.ofl-upload-area:hover {
  border-color: var(--accent, #0f766e);
}

.ofl-upload-area h3 {
  margin: 0 0 8px;
  color: var(--ink, #1f2937);
  font-size: 1.25rem;
}

.ofl-upload-area p {
  margin: 0 0 24px;
  color: var(--ink, #1f2937);
}

.ofl-file-info {
  margin-top: 16px;
}

.ofl-help-text {
  margin: 0;
  color: var(--ink, #1f2937);
  font-size: var(--font-size-sm, 0.8125rem);
}

/* ── Focus, for everything clickable in here ────────────────────────────── */

.ofl-toggle-btn:focus-visible,
.ofl-sort-btn:focus-visible,
.ofl-btn:focus-visible {
  outline: 3px solid var(--accent, #0f766e);
  outline-offset: 2px;
}

/* ── The quieter lines ──────────────────────────────────────────────────────
   Secondary text is a mix of the app's own ink and panel rather than a fixed
   grey, so it stays a fixed *proportion* of whatever contrast that app has
   chosen instead of a fixed colour that only works on white. Guarded, so a
   browser without color-mix keeps full-strength ink — less pretty, never
   unreadable. */
@supports (color: color-mix(in srgb, red 70%, white)) {
  .ofl-subtitle,
  .ofl-count,
  .ofl-item-date,
  .ofl-empty p,
  .ofl-upload-area p,
  .ofl-help-text {
    color: color-mix(in srgb, var(--ink, #1f2937) 82%, var(--panel, #fff));
  }
}

@supports (background: color-mix(in srgb, red 12%, white)) {
  .ofl-toggle-btn:hover:not(.active),
  .ofl-btn:hover:not(:disabled),
  .ofl-sort-btn:hover:not(.active) {
    background: color-mix(in srgb, var(--ink, #1f2937) 6%, var(--panel, #fff));
  }
  .ofl-toggle-btn.active,
  .ofl-sort-btn.active,
  .ofl-btn-primary {
    background: color-mix(in srgb, var(--accent, #0f766e) 12%, var(--panel, #fff));
  }
  .ofl-btn-danger {
    background: color-mix(in srgb, var(--danger, #b3261e) 12%, var(--panel, #fff));
  }
}

/* ── Touch ──────────────────────────────────────────────────────────────── */

@media (hover: none) and (pointer: coarse) {
  .ofl-item {
    min-height: 80px;
    padding: 20px 16px;
  }
  .ofl-btn,
  .ofl-item,
  .ofl-sort-btn,
  .ofl-toggle-btn {
    -webkit-tap-highlight-color: rgba(15, 118, 110, 0.2);
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
  /* A hover style on a touch screen sticks after the finger lifts. */
  .ofl-item:hover,
  .ofl-upload-area:hover {
    border-color: var(--line, #d1d5db);
  }
  .ofl-btn:active,
  .ofl-toggle-btn:active {
    transform: scale(0.97);
  }
}

/* ── Narrow screens ─────────────────────────────────────────────────────── */

@media (max-width: 640px) {
  .ofl-item {
    flex-direction: column;
    align-items: flex-start;
  }
  .ofl-item-actions {
    width: 100%;
  }
  .ofl-btn {
    flex: 1;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE "SAVE YOUR DRAWING" DIALOG  (saveToLocal.js)
   ══════════════════════════════════════════════════════════════════════════
   These rules style what is INSIDE the dialog. The panel, the backdrop, the
   heading, the close button and the footer buttons are the shared dialog's
   job — see `css/core/modals.css`.

   Every colour is a token with a light-mode fallback, for the reason set out
   at length above the picker's block: fixed colours on a themed panel are how
   you get 1.07:1 text in dark mode.
   ══════════════════════════════════════════════════════════════════════════ */

.stl-subtitle {
  margin: 0 0 1.25rem;
  color: var(--ink, #1f2937);
  font-size: var(--font-size-sm, 0.875rem);
}

/* ── One step of the form ───────────────────────────────────────────────── */

.stl-step {
  margin: 0 0 1.25rem;
  padding: 0;
  border: 0;
}

.stl-step-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  padding: 0;
  font-weight: 600;
  color: var(--ink, #1f2937);
}

.stl-step-icon {
  font-size: 1.1em;
  line-height: 1;
}

/* ── The name field ─────────────────────────────────────────────────────── */

.stl-name-input {
  width: 100%;
  min-height: var(--min-touch-target, 44px);
  padding: 10px 12px;
  color: var(--ink, #1f2937);
  background: var(--panel, #fff);
  border: 2px solid var(--line, #d1d5db);
  border-radius: var(--radius-sm, 8px);

  /* 16px, and not a pixel less.

     iOS Safari zooms the whole page in when a text field smaller than 16px
     receives focus, and does not zoom back out afterwards — so the child taps
     the name box and the app appears to break. This used to be worked around
     in JavaScript, by measuring the computed font size on focus and setting it
     to 16px, then restoring it on blur. That is a real fix in the wrong place;
     the size just needs to be right to begin with. */
  font-family: inherit;
  font-size: 16px;
}

.stl-name-input:focus-visible {
  outline: 3px solid var(--accent, #0f766e);
  outline-offset: 2px;
}

.stl-name-input.error {
  border-color: var(--danger, #b3261e);
}

.stl-name-counter {
  margin-top: 4px;
  text-align: right;
  font-size: var(--font-size-sm, 0.8125rem);
  color: var(--ink, #1f2937);
}

.stl-name-counter.stl-warning {
  font-weight: 700;
  color: var(--danger, #b3261e);
}

.stl-error-message {
  display: none;
  margin-top: 6px;
  font-size: var(--font-size-sm, 0.875rem);
  font-weight: 600;
  color: var(--ink, #1f2937);
}

/* ── Choosing where to save ─────────────────────────────────────────────── */

.stl-save-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.stl-option-card {
  display: block;
  padding: 14px;
  border: 2px solid var(--line, #d1d5db);
  border-radius: var(--radius-sm, 8px);
  cursor: pointer;
}

.stl-option-card:hover {
  border-color: var(--line-strong, #93a3b5);
}

.stl-option-card.stl-option-active {
  border-color: var(--accent, #0f766e);
}

/* The radio itself is kept in the accessibility tree and reachable by
   keyboard — the card is only a bigger place to click. Hiding it with
   `display: none` would take it out of the tab order entirely. */
.stl-option-card input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.stl-option-card:focus-within {
  outline: 3px solid var(--accent, #0f766e);
  outline-offset: 2px;
}

.stl-option-content {
  display: flex;
  align-items: center;
  gap: 12px;
}

.stl-option-icon {
  font-size: 1.6rem;
  line-height: 1;
}

.stl-option-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.stl-option-text strong {
  color: var(--ink, #1f2937);
}

.stl-option-text span,
.stl-storage-status {
  font-size: var(--font-size-sm, 0.875rem);
  color: var(--ink, #1f2937);
}

/* ── What will happen ───────────────────────────────────────────────────── */

.stl-format-info {
  margin: 0 0 1rem;
  padding: 12px;
  border-left: 4px solid var(--accent, #0f766e);
  border-radius: var(--radius-sm, 8px);
}

.stl-format-text {
  font-size: var(--font-size-sm, 0.875rem);
  color: var(--ink, #1f2937);
}

/* ── How it went ────────────────────────────────────────────────────────── */

.stl-success-message,
.stl-error-display {
  display: none;
  margin-top: 1rem;
  padding: 12px;
  border-radius: var(--radius-sm, 8px);
  border: 2px solid var(--line, #d1d5db);
  color: var(--ink, #1f2937);
}

.stl-success-message.active,
.stl-error-display.active {
  display: block;
}

.stl-success-message {
  border-color: var(--success, #1b5e20);
}

.stl-error-display {
  border-color: var(--danger, #b3261e);
}

.stl-success-text {
  margin: 0 0 4px;
  font-weight: 700;
}

.stl-success-hint,
.stl-error-text {
  margin: 0;
  font-size: var(--font-size-sm, 0.875rem);
}

.stl-error-retry {
  margin-top: 8px;
  min-height: var(--min-touch-target, 44px);
  padding: 8px 16px;
  font: inherit;
  font-weight: 600;
  color: var(--ink, #1f2937);
  background: var(--panel, #fff);
  border: 2px solid var(--line-strong, #93a3b5);
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
}

.stl-error-retry:focus-visible {
  outline: 3px solid var(--accent, #0f766e);
  outline-offset: 2px;
}

/* ── Tints, where the browser can mix them ──────────────────────────────── */

@supports (background: color-mix(in srgb, red 12%, white)) {
  .stl-option-card.stl-option-active {
    background: color-mix(in srgb, var(--accent, #0f766e) 10%, var(--panel, #fff));
  }
  .stl-option-card:hover:not(.stl-option-active),
  .stl-error-retry:hover {
    background: color-mix(in srgb, var(--ink, #1f2937) 6%, var(--panel, #fff));
  }
  .stl-format-info {
    background: color-mix(in srgb, var(--accent, #0f766e) 8%, var(--panel, #fff));
  }
  .stl-success-message {
    background: color-mix(in srgb, var(--success, #1b5e20) 10%, var(--panel, #fff));
  }
  .stl-error-display {
    background: color-mix(in srgb, var(--danger, #b3261e) 10%, var(--panel, #fff));
  }
}

@supports (color: color-mix(in srgb, red 70%, white)) {
  .stl-subtitle,
  .stl-name-counter,
  .stl-option-text span,
  .stl-storage-status,
  .stl-format-text,
  .stl-success-hint,
  .stl-error-text {
    color: color-mix(in srgb, var(--ink, #1f2937) 82%, var(--panel, #fff));
  }
}

/* The counter turning into a warning must beat the quieter colour above. */
.stl-name-counter.stl-warning,
.stl-error-message {
  color: var(--ink, #1f2937);
}

/* ── Version history: School Sounds modal interface ───────────────────── */
.version-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
  max-height: min(320px, 45vh);
  overflow-y: auto;
  scrollbar-width: thin;
}

.version-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid #dfe3eb;
  border-radius: 10px;
  background: #fff;
}

.version-thumb {
  flex: none;
  width: 104px;
  height: 60px;
  border: 1px solid #dfe3eb;
  border-radius: 8px;
  background: #fff;
  object-fit: contain;
}

.version-info {
  display: grid;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}

.version-heading {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

.version-heading strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.version-number {
  flex: none;
  padding: 1px 7px;
  border-radius: 999px;
  background: #eef2ff;
  color: #3730a3;
  font-size: 0.78rem;
  font-weight: 700;
}

.version-meta {
  overflow-wrap: anywhere;
  color: var(--muted, #4a5568);
  font-size: 0.84rem;
}

.version-description {
  font-size: 0.8rem;
}

.version-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
}

.version-restore {
  min-height: 42px;
}

.version-delete {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  padding: 0;
  border: 1px solid #fecaca;
  border-radius: 8px;
  background: #fff;
  color: var(--danger, #ef4444);
  cursor: pointer;
}

.version-delete svg {
  width: 22px;
  height: 22px;
}

.version-delete:hover {
  border-color: var(--danger, #ef4444);
  background: #fef2f2;
}

.version-delete:focus-visible,
.version-restore:focus-visible {
  outline: 3px solid var(--focus, #7a2e00);
  outline-offset: 2px;
}

.version-empty {
  padding: 24px 12px;
  color: var(--muted, #4a5568);
  text-align: center;
}

@media (max-width: 520px) {
  .version-item {
    flex-wrap: wrap;
  }

  .version-info {
    flex: 1 1 120px;
  }

  .version-actions {
    width: 100%;
    justify-content: flex-end;
  }
}
