/* ==================================================================
   amirkral.ir — layout layer
   Loading screen, lock screen, desktop, taskbar, start menu, windows,
   context menus and the settings window.
   ================================================================== */

/* ==================================================================
   Full-screen overlays
   ================================================================== */
.screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-screen);
  transition: opacity 0.5s ease-out;
}
.screen.is-hidden {
  opacity: 0;
  pointer-events: none;
}

/* ---------- Loading screen --------------------------------------- */
#loading-screen { background-color: #000; color: #fff; }

.loader {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loader__bars {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0.5rem;
  direction: ltr;
  font-size: 0.8rem;
  font-weight: 600;
}
@media (min-width: 768px) {
  .loader__bars { gap: 1rem; font-size: 1rem; }
}

.candle {
  display: flex;
  flex-direction: column;
  align-items: center;
  opacity: 0;
  transition: opacity 0.8s ease-out, transform 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.candle--down { transform: translateY(-40px); }
.candle--up   { transform: translateY(40px); }
.candle.is-visible { opacity: 1; transform: translateY(0); }

.candle__word { margin-bottom: 0.5rem; height: 1.5rem; }
.candle__shape { display: flex; flex-direction: column; align-items: center; }
.candle__wick { width: 2px; }
.candle__body { width: 1rem; }
.candle--down .candle__wick,
.candle--down .candle__body { background-color: var(--down); }
.candle--up .candle__wick,
.candle--up .candle__body { background-color: var(--up); }

.loader__signature {
  position: absolute;
  bottom: 2.5rem;
  width: 100%;
  text-align: center;
  font-family: 'Exo 2', sans-serif;
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 1.2s ease-out, transform 1.2s ease-out;
}
.loader__signature.is-visible { opacity: 1; transform: translateY(0); }
.loader__signature strong {
  display: block;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: #d1d5db;
}
.loader__signature span { font-size: 0.9rem; color: #9ca3af; }

/* ---------- Lock / login screen ---------------------------------- */
#login-screen {
  background-color: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  overflow: hidden;
  color: #fff;
}

.lock,
.login-form-wrap {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: transform 0.5s var(--ease);
}
.lock { cursor: pointer; }
.login-form-wrap { transform: translateY(100%); }

#login-screen.is-unlocking .lock { transform: translateY(-100%); }
#login-screen.is-unlocking .login-form-wrap { transform: translateY(0); }

.lock__time { font-size: clamp(3rem, 12vw, 6rem); font-weight: 700; line-height: 1; }
.lock__date { font-size: clamp(1rem, 3vw, 1.5rem); margin-top: 0.6rem; opacity: 0.95; }
.lock__hint {
  position: absolute;
  bottom: 2.5rem;
  text-align: center;
  font-size: 1rem;
  opacity: 0.9;
}
.lock__hint svg { width: 1.5rem; height: 1.5rem; margin: 0 auto 0.25rem; animation: bounce 1.6s infinite; }
@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-25%); }
}

.login-card { text-align: center; }
.login-card__avatar {
  width: 8rem;
  height: 8rem;
  object-fit: cover;
  border-radius: 50%;
  margin: 0 auto 1rem;
  border: 4px solid rgba(255, 255, 255, 0.5);
}
.login-card__name { font-size: 2rem; font-weight: 700; margin: 0; }

.login-form {
  margin-top: 1.2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}
.login-form input {
  width: 16rem;
  padding: 0.75rem;
  text-align: center;
  color: #fff;
  background-color: rgba(0, 0, 0, 0.3);
  border: 2px solid rgba(255, 255, 255, 0.5);
  border-radius: var(--radius-sm);
  transition: border-color 0.2s ease;
}
.login-form input::placeholder { color: rgba(255, 255, 255, 0.7); }
.login-form input:focus { border-color: #fff; outline: none; }
.login-form .btn { width: 16rem; border-radius: var(--radius-sm); }
.login-error { color: #fca5a5; margin-top: 0.5rem; min-height: 1.25rem; font-size: 0.85rem; }

/* ==================================================================
   Desktop
   ================================================================== */
#desktop {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  z-index: var(--z-desktop);
}
#desktop[hidden] { display: none; }

.draggable { position: absolute; }
.draggable.is-dragging { transition: none !important; }

/* ==================================================================
   Taskbar
   ================================================================== */
.taskbar {
  position: absolute;
  bottom: 1rem;
  width: 100%;
  padding: 0 1rem;
  pointer-events: none;
  z-index: var(--z-taskbar);
}

.taskbar__group {
  position: absolute;
  bottom: 0;
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  pointer-events: auto;
}
.taskbar__group--left { inset-inline-start: 1rem; }
.taskbar__group--center { left: 50%; transform: translateX(-50%); }
.taskbar__group--right { inset-inline-end: 1rem; align-items: center; }

.taskbar__dock {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 0.5rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.taskbar__dock .icon-btn { width: 2.5rem; height: 2.5rem; }
.taskbar__dock .icon-btn img { width: 1.75rem; height: 1.75rem; }
/* Start and search share one dock, so they are sized identically and
   centred on the same baseline — previously the two icons were set from
   different rules and did not line up. */
.taskbar__group--center .icon-btn { width: 3rem; height: 3rem; }
.taskbar__group--center .icon-btn img,
.taskbar__group--center .icon-btn > svg,
.taskbar__group--center .icon-btn .icon-svg,
.taskbar__group--center .icon-btn .icon-svg svg {
  width: 1.65rem;
  height: 1.65rem;
}
.taskbar__group--center .icon-btn .icon-svg {
  display: flex;
  align-items: center;
  justify-content: center;
}
.taskbar__group--center .start-btn svg { width: 1.65rem; height: 1.65rem; }

.start-btn svg { width: 1.5rem; height: 1.5rem; color: var(--brand); }

.lang-btn {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  font-weight: 600;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
}
.lang-btn:hover { background-color: var(--glass-hover); }

.notif-btn {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  position: relative;
}
.notif-btn:hover { background-color: var(--glass-hover); }
.notif-btn svg { width: 1.5rem; height: 1.5rem; }
.notif-btn__count {
  position: absolute;
  top: 0.35rem;
  inset-inline-end: 0.35rem;
  min-width: 1.05rem;
  height: 1.05rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--brand);
  color: var(--brand-contrast);
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 1.05rem;
  text-align: center;
  box-shadow: 0 0 0 2px var(--glass-bg);
}

.theme-dock {
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
}

/* Theme switch */
.switch { position: relative; display: inline-block; width: 3.5rem; height: 2rem; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  position: absolute;
  inset: 0;
  background-color: #cbd5e1;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.35s ease;
}
.switch__track::before {
  content: '';
  position: absolute;
  top: 0.25rem;
  inset-inline-start: 0.25rem;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background-color: #fff;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0.85rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='2.5' stroke='%23374151'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707m12.728 10.607a4.5 4.5 0 11-6.364-6.364 4.5 4.5 0 016.364 6.364z'/%3E%3C/svg%3E");
  transition: transform 0.35s ease, background-image 0.35s ease;
}
.switch input:checked + .switch__track { background-color: #374151; }
.switch input:checked + .switch__track::before {
  transform: translateX(1.5rem);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23ffffff'%3E%3Cpath d='M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z'/%3E%3C/svg%3E");
}
html[dir='rtl'] .switch input:checked + .switch__track::before { transform: translateX(-1.5rem); }

/* Small switch used inside settings lists */
.switch--sm { width: 2.75rem; height: 1.6rem; }
.switch--sm .switch__track::before { width: 1.1rem; height: 1.1rem; top: 0.25rem; background-size: 0.7rem; }
.switch--sm input:checked + .switch__track::before { transform: translateX(1.15rem); }
html[dir='rtl'] .switch--sm input:checked + .switch__track::before { transform: translateX(-1.15rem); }

/* ==================================================================
   Pop-over panels (start menu, search, notifications, small menus)
   ================================================================== */
.popover {
  position: absolute;
  z-index: var(--z-menu);
  transition: opacity 0.2s var(--ease), transform 0.22s var(--ease);
}
.popover.is-hidden {
  opacity: 0;
  pointer-events: none;
  transform: translateY(14px) scale(0.96);
}

.panel-bottom-center {
  bottom: 6rem;
  /* `left` + translateX is used instead of the logical inset-inline-start +
     margin-inline-start pairing on purpose: mixing a physical property
     (left) with a logical one (margin-inline-start) breaks in RTL, because
     inline-start flips to the right while `left` does not — the panel
     rendered off-center in Persian and Turkish. translateX(-50%) shifts by
     the element's own rendered width regardless of text direction, so
     centering is correct in both directions. */
  left: 50%;
  transform: translateX(-50%);
  transform-origin: bottom center;
  width: 600px;
  max-width: 95vw;
  height: 550px;
  max-height: 70vh;
}
.panel-bottom-center.is-hidden { transform: translateX(-50%) translateY(14px) scale(0.96); }

.panel-body {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  color: var(--text);
}

/* ---------- Start menu ------------------------------------------- */
.start__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.start__profile {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem;
  margin: -0.5rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.start__profile:hover { background-color: var(--glass-hover); }
.start__profile img { width: 2.5rem; height: 2.5rem; border-radius: 50%; object-fit: cover; }
.start__profile span { font-weight: 600; }

/* Tabs scroll sideways instead of wrapping onto a second row: with many
   categories, wrapping quietly ate the height the app grid needed. The
   scrollbar is the same understated one the cards use. */
.tabs {
  display: flex;
  justify-content: flex-start;
  flex-wrap: nowrap;
  gap: 0.35rem;
  border-bottom: 1px solid var(--divider);
  margin-bottom: 1.35rem;
  padding-bottom: 0.15rem;
  font-size: 0.85rem;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
/* Centre them while they still fit; only start scrolling once they don't. */
.tabs::before, .tabs::after { content: ''; margin: auto; }
.tabs::-webkit-scrollbar { height: 4px; }
.tabs::-webkit-scrollbar-track { background: transparent; }
.tabs::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 999px; }
.tabs::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); }

.tabs button {
  padding: 0.5rem 0.9rem;
  color: var(--text-soft);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  flex-shrink: 0;
  border-radius: 8px 8px 0 0;
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}
.tabs button:hover { color: var(--text); background-color: var(--glass-hover); }
.tabs button.is-active {
  color: var(--brand);
  font-weight: 600;
  border-bottom-color: var(--brand);
}

.app-grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.35rem 1rem;
  padding-block: 0.35rem;
  padding-inline-end: 0.5rem;
  align-content: start;
}
@media (min-width: 520px) {
  .app-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  .tabs { scroll-behavior: auto; }
}

.app-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  text-align: center;
  cursor: pointer;
}
/* Icon tile: a soft flat square tinted by its category's accent colour
   (set by the admin per start-menu tab) — gives icons a distinct, designed
   identity without needing new artwork. Size and corner shape are both
   driven by admin settings (--app-icon-size, --app-icon-radius) so the
   whole grid restyles together. */
.app-tile__icon {
  --tile-pad: calc(var(--app-icon-size, 40px) * 0.32);
  --tile-tint: var(--tile-accent, var(--brand));
  width: calc(var(--app-icon-size, 40px) + var(--tile-pad));
  height: calc(var(--app-icon-size, 40px) + var(--tile-pad));
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--app-icon-radius, 13px);
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--tile-tint) 20%, transparent),
    color-mix(in srgb, var(--tile-tint) 8%, transparent));
  border: 1px solid color-mix(in srgb, var(--tile-tint) 30%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.app-tile:hover .app-tile__icon {
  transform: translateY(-2px) scale(1.05);
  border-color: color-mix(in srgb, var(--tile-tint) 55%, transparent);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--tile-tint) 25%, transparent),
              inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.app-tile__icon img,
.app-tile__icon svg {
  width: var(--app-icon-size, 40px);
  height: var(--app-icon-size, 40px);
  object-fit: contain;
}
.app-tile__icon img { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.12)); }
/* Inlined SVGs take the category accent; a touch heavier than the source
   stroke so they stay legible at small sizes. */
.app-tile__icon svg {
  color: var(--tile-tint);
  stroke-width: 1.6;
}
html.dark .app-tile__icon svg { color: color-mix(in srgb, var(--tile-tint) 78%, white); }
.app-tile__name {
  font-size: 0.78rem;
  line-height: 1.3;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-tile__desc {
  font-size: 0.68rem;
  color: var(--text-soft);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.start__foot {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--divider);
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
.start__foot .icon-btn { width: 2.25rem; height: 2.25rem; border-radius: 50%; }

/* ---------- Search ------------------------------------------------ */
.search-input {
  width: 100%;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  border: 0;
  border-radius: var(--radius-sm);
  background-color: rgba(255, 255, 255, 0.5);
  color: var(--text);
  outline: none;
  transition: box-shadow 0.2s ease, background-color 0.2s ease;
}
html.dark .search-input { background-color: rgba(0, 0, 0, 0.25); }
.search-input:focus { box-shadow: 0 0 0 2px var(--brand); }
.search-input::placeholder { color: var(--text-soft); }

.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  padding: 2rem 1rem;
  color: var(--text-soft);
  font-size: 0.85rem;
}

/* ---------- Small menus ------------------------------------------ */
.menu {
  border-radius: var(--radius-sm);
  padding: 0.25rem;
  font-size: 0.85rem;
  min-width: 11rem;
  box-shadow: var(--shadow-lg);
  color: var(--text);
}
.menu button {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  text-align: start;
  transition: background-color 0.15s ease;
}
.menu button:hover { background-color: var(--glass-hover); }
.menu button svg { width: 1rem; height: 1rem; flex-shrink: 0; }

#context-menu { min-width: 14rem; transform-origin: top left; }
#power-menu, #profile-menu, #language-menu, #notification-center { bottom: 5rem; }
#language-menu, #notification-center { inset-inline-end: 1rem; }

/* The power and profile buttons both live inside the centred start menu,
   so their menus open centred under it rather than jumping to a screen
   edge far away from the button that opened them. Centering uses
   translateX(-50%) rather than a logical inset so it is correct in RTL
   and LTR alike; the hidden state has to restate the translate or the
   generic .popover.is-hidden rule would knock it off-centre. */
#power-menu, #profile-menu {
  left: 50%;
  bottom: 7.5rem;
  transform: translateX(-50%);
  transform-origin: bottom center;
  min-width: 13rem;
}
#power-menu.is-hidden, #profile-menu.is-hidden {
  transform: translateX(-50%) translateY(14px) scale(0.96);
}
#power-menu button, #profile-menu button { justify-content: center; }

#language-menu {
  display: flex;
  gap: 0.5rem;
  padding: 0.5rem;
  border-radius: var(--radius);
}
#language-menu button {
  width: auto;
  padding: 0.25rem;
  border: 2px solid transparent;
  border-radius: 50%;
}
#language-menu button.is-active { border-color: var(--brand); }
#language-menu img { width: 2rem; height: 2rem; border-radius: 50%; object-fit: cover; }

/* ---------- Notification centre ---------------------------------- */
#notification-center {
  width: 22rem;
  max-width: calc(100vw - 2rem);
  max-height: 26rem;
  padding: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  color: var(--text);
  overflow: hidden;
}
#notification-center h3 {
  margin: 0;
  padding: 1rem 1.1rem 0.75rem;
  font-size: 0.92rem;
  font-weight: 700;
  border-bottom: 1px solid var(--divider);
}
.notif-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.75rem;
}

.notif-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 2rem 1rem;
  color: var(--text-soft);
  font-size: 0.82rem;
  text-align: center;
}
.notif-empty svg { width: 2rem; height: 2rem; opacity: 0.55; }

.notif {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.7rem 0.75rem;
  border-radius: var(--radius-sm);
  background-color: rgba(255, 255, 255, 0.32);
  border-inline-start: 3px solid var(--notif-accent, var(--brand));
  transition: background-color 0.15s ease, transform 0.15s ease;
}
.notif:hover { transform: translateX(-2px); }
html[dir='rtl'] .notif:hover { transform: translateX(2px); }
html.dark .notif { background-color: rgba(255, 255, 255, 0.05); }

.notif__icon {
  flex-shrink: 0;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: color-mix(in srgb, var(--notif-accent, var(--brand)) 16%, transparent);
  color: var(--notif-accent, var(--brand));
}
.notif__icon svg { width: 1.05rem; height: 1.05rem; }
.notif__icon img { width: 1.4rem; height: 1.4rem; object-fit: contain; border-radius: 50%; }

.notif__body { min-width: 0; }
.notif__body strong {
  display: block;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-strong);
  line-height: 1.5;
}
.notif__body p {
  margin: 0.15rem 0 0;
  font-size: 0.76rem;
  color: var(--text-soft);
  line-height: 1.6;
}

.notif--info    { --notif-accent: #3b82f6; }
.notif--success { --notif-accent: #22c55e; }
.notif--warning { --notif-accent: #f59e0b; }
.notif--danger  { --notif-accent: #ef4444; }
html.dark .notif--info    { --notif-accent: #60a5fa; }
html.dark .notif--success { --notif-accent: #4ade80; }
html.dark .notif--warning { --notif-accent: #fbbf24; }
html.dark .notif--danger  { --notif-accent: #f87171; }

/* ==================================================================
   Windows
   ================================================================== */
.window {
  position: absolute;
  z-index: var(--z-window);
  display: flex;
  flex-direction: column;
  min-width: 320px;
  min-height: 240px;
  max-width: calc(100vw - 2rem);
  max-height: calc(100vh - 8rem);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  resize: both;
  color: var(--text);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
}
.window.is-hidden {
  opacity: 0;
  pointer-events: none;
  transform: scale(0.96);
}

.window__header {
  flex-shrink: 0;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1rem;
  border-bottom: 1px solid var(--divider);
  cursor: grab;
  font-weight: 700;
  font-size: 0.9rem;
}
.window__header:active { cursor: grabbing; }

.window__close {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background-color: #ef4444;
  transition: background-color 0.15s ease;
  flex-shrink: 0;
}
.window__close:hover { background-color: #dc2626; }

.window__body {
  flex: 1;
  padding: 1.25rem;
  overflow-y: auto;
  font-size: 0.88rem;
  line-height: 1.75;
}
.window__body h1, .window__body h2, .window__body h3 { color: var(--text-strong); }
.window__body h3 {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 1.5rem 0 0.75rem;
  padding-bottom: 0.3rem;
  border-bottom: 2px solid var(--brand);
}
.window__body ul { padding-inline-start: 1.2rem; margin: 0.5rem 0; }
.window__body a { color: var(--brand); }
.window__body img { border-radius: var(--radius-sm); margin: 0.5rem 0; max-width: 100%; }

/* Content authored in the panel's editor: headings, tables, quotes and
   code blocks all need to look right here, not just in the editor. */
.window__body h2 { font-size: 1.15rem; font-weight: 700; margin: 1.1rem 0 .55rem; }
.window__body h4 { font-size: .95rem; font-weight: 700; margin: .9rem 0 .4rem; color: var(--text-strong); }
.window__body p { margin: 0 0 .7rem; }
.window__body ol { padding-inline-start: 1.3rem; margin: 0.5rem 0; }
.window__body blockquote {
  margin: 0.8rem 0;
  padding: 0.55rem 0.9rem;
  border-inline-start: 3px solid var(--brand);
  background: rgba(255, 255, 255, 0.14);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
html.dark .window__body blockquote { background: rgba(0, 0, 0, 0.18); }
.window__body pre {
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.16);
  direction: ltr;
  text-align: left;
  overflow-x: auto;
  font-size: 0.78rem;
}
.window__body table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.8rem 0;
  font-size: 0.82rem;
}
.window__body th, .window__body td {
  border: 1px solid var(--divider);
  padding: 0.4rem 0.6rem;
  text-align: start;
}
.window__body th { background: rgba(255, 255, 255, 0.12); font-weight: 700; }
html.dark .window__body th { background: rgba(0, 0, 0, 0.22); }

.window--centered .window__body {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 1.05rem;
  font-weight: 600;
}

/* Resume window layout */
.resume__head { text-align: center; margin-bottom: 1.5rem; }
.resume__head img {
  width: 6rem;
  height: 6rem;
  object-fit: cover;
  border-radius: 50%;
  margin: 0 auto 0.75rem;
  border: 4px solid rgba(255, 255, 255, 0.5);
}
.resume__head h2 { font-size: 1.4rem; font-weight: 700; margin: 0; }
.resume__head p { margin: 0.25rem 0 0; color: var(--text-soft); }

.skills { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 1.5rem; }
.skill__row { display: flex; justify-content: space-between; font-size: 0.8rem; margin-bottom: 0.3rem; }
.skill__bar { height: 0.5rem; border-radius: 999px; background-color: var(--divider); overflow: hidden; }
.skill__fill { height: 100%; border-radius: 999px; background-color: var(--brand); }

/* ==================================================================
   Display-settings window
   ================================================================== */
.settings-section { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--divider); }
.settings-section:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.settings-section h3 { font-size: 0.95rem; font-weight: 700; margin: 0 0 0.85rem; border: 0; padding: 0; }

.wallpaper-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5rem; }
.wallpaper-grid button {
  height: 4.5rem;
  border-radius: var(--radius-sm);
  border: 2px solid transparent;
  background-size: cover;
  background-position: center;
  transition: border-color 0.2s ease, transform 0.15s ease;
}
.wallpaper-grid button:hover { transform: scale(1.03); }
.wallpaper-grid button.is-active { border-color: var(--brand); }

.color-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.color-dot {
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  border: 2px solid transparent;
  transition: transform 0.2s ease, border-color 0.2s ease;
}
.color-dot.is-active {
  border-color: #fff;
  transform: scale(1.12);
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
}

.range-row { display: flex; align-items: center; gap: 1rem; font-size: 0.8rem; }
.range-row input[type='range'] {
  flex: 1;
  height: 0.45rem;
  border-radius: 999px;
  appearance: none;
  background: var(--divider);
  cursor: pointer;
}
.range-row input[type='range']::-webkit-slider-thumb {
  appearance: none;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  background: var(--brand);
  border: 2px solid #fff;
}
.range-row input[type='range']::-moz-range-thumb {
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--brand);
}

/* Three per row: the toggles are short labels with a small switch, and
   two columns left a lot of empty space in a window this wide. */
.toggle-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.6rem 0.9rem; }
.toggle-grid .toggle-row { font-size: 0.78rem; gap: 0.4rem; }

/* Two controls sharing a row. */
.settings-section--split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}
.settings-section--split > div { min-width: 0; }

@media (max-width: 640px) {
  .toggle-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .settings-section--split { grid-template-columns: 1fr; gap: 0.9rem; }
}
.toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: 0.85rem; }

/* ==================================================================
   Mobile
   ================================================================== */
@media (max-width: 767px) {
  body { overflow: auto; }

  #desktop {
    height: auto;
    min-height: 100vh;
    overflow-y: auto;
    padding: 1.5rem 1rem 7rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
  }

  .draggable { position: static !important; width: 100% !important; }

  .taskbar { position: fixed; bottom: 0.75rem; }
  .taskbar__group--left { display: none; }
  .taskbar__group--center { bottom: 0; }
  .taskbar__group--right { inset-inline-end: 0.75rem; }
  .taskbar__group--right .notif-btn,
  .taskbar__group--right .lang-btn { width: 2.5rem; height: 2.5rem; }
  .taskbar__group--right .theme-dock { padding: 0.35rem 0.5rem; }
  .switch { width: 2.75rem; height: 1.6rem; }
  .switch__track::before { width: 1.1rem; height: 1.1rem; background-size: 0.7rem; }
  .switch input:checked + .switch__track::before { transform: translateX(1.15rem); }
  html[dir='rtl'] .switch input:checked + .switch__track::before { transform: translateX(-1.15rem); }

  .panel-bottom-center,
  .panel-bottom-center.is-hidden {
    bottom: 5.5rem;
    height: auto;
    max-height: 65vh;
    left: 1rem;
    right: 1rem;
    width: auto;
    transform: none;
  }
  .panel-body { padding: 1rem; }

  .window {
    inset-inline-start: 0.5rem !important;
    inset-inline-end: 0.5rem;
    width: auto !important;
    max-height: 78vh;
    resize: none;
  }

  .wallpaper-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .skills { grid-template-columns: 1fr; }
}

/* Social card shown only on mobile */
.social-card {
  display: none;
  align-items: center;
  justify-content: space-around;
  gap: 0.5rem;
  padding: 1rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.social-card img { width: 1.75rem; height: 1.75rem; }
@media (max-width: 767px) { .social-card { display: flex; } }

/* ==================================================================
   Taskbar tray — live clock, calendar and weather
   These replace the desktop cards that used to hold the same
   information, so the desktop is free for the cards that need room.
   ================================================================== */
#taskbar-tray { gap: 0.15rem; }

.tray-btn { width: 2.5rem; height: 2.5rem; }
.tray-btn svg, .tray-btn .tray-weather__icon svg { width: 1.5rem; height: 1.5rem; }
.tray-btn .tray-weather__icon { display: flex; }

/* ---------- clock icon ---------- */
.tray-clock__face { fill: none; stroke: currentColor; stroke-width: 1.6; opacity: 0.85; }
.tray-clock__tick { stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; opacity: 0.5; }
.tray-clock__hour,
.tray-clock__minute {
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.tray-clock__minute { stroke-width: 1.4; }
.tray-clock__second {
  stroke: var(--down);
  stroke-width: 1;
  stroke-linecap: round;
  transition: transform 0.15s cubic-bezier(0.34, 1.5, 0.64, 1);
}
.tray-clock__pin { fill: var(--down); }

/* ---------- calendar icon ---------- */
.tray-cal__body { fill: currentColor; opacity: 0.16; stroke: currentColor; stroke-width: 1.3; }
.tray-cal__band { fill: var(--brand); }
.tray-cal__ring { fill: currentColor; opacity: 0.75; }
.tray-cal__day {
  fill: currentColor;
  font-size: 9px;
  font-weight: 700;
  font-family: 'Vazirmatn', system-ui, sans-serif;
}

/* ---------- weather glyphs ---------- */
.wx-sun { fill: #fbbf24; }
.wx-ray { stroke: #fbbf24; stroke-width: 1.6; stroke-linecap: round; }
.wx-cloud { fill: #e2e8f0; stroke: #cbd5e1; stroke-width: 0.8; }
html.dark .wx-cloud { fill: #cbd5e1; stroke: #94a3b8; }
.wx-rain { stroke: #60a5fa; stroke-width: 1.5; stroke-linecap: round; }
.wx-snow { fill: #bfdbfe; }
.wx-moon { fill: #fde68a; }
.wx-star { fill: #fbbf24; }
.wx-bolt { fill: #f59e0b; }

/* ---------- panels ---------- */
/* Centred over the taskbar and shaped like the notification centre, so
   the three read as one family of panels rather than three variations.
   translateX is restated on the hidden state or the shared .popover rule
   would knock them off centre on the way in. */
/* Positioned in script, above whichever icon opened it (see ui/tray.js).
   The left and bottom values here are only a sensible starting point for
   the first paint. */
.tray-panel {
  bottom: 5.5rem;
  left: 50%;
  transform-origin: bottom center;
  width: 19rem;
  padding: 1.1rem;
  /* No scrolling: each panel is small enough to show whole, and a
     scrollbar inside a popover this size looks like a mistake. The cap is
     only a guard for very short viewports. */
  max-height: calc(100vh - 8rem);
  overflow: visible;
  border-radius: var(--radius-lg, 22px);
  text-align: center;
}
.tray-panel.is-hidden { transform: translateY(14px) scale(0.96); }

/* Small pointer toward the icon that opened the panel. */
.tray-panel::after {
  content: '';
  position: absolute;
  top: 100%;
  left: var(--tray-arrow, 50%);
  margin-left: -7px;
  border: 7px solid transparent;
  border-top-color: var(--glass-bg);
  filter: drop-shadow(0 1px 0 var(--glass-border));
}
.tray-panel--wide { width: 20rem; }

.tray-panel__title {
  font-size: 0.82rem;
  font-weight: 700;
  margin-bottom: 0.85rem;
  color: var(--text-strong);
  text-align: center;
}
.tray-panel__state { font-size: 0.8rem; color: var(--text-soft); text-align: center; padding: 1rem 0; }

/* ---------- clock panel ---------- */
.tray-local { text-align: center; padding-bottom: 0.7rem; margin-bottom: 0.6rem; border-bottom: 1px solid var(--divider); }
.tray-local__time {
  display: block;
  font-size: 1.7rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.tray-local__label { font-size: 0.68rem; color: var(--text-soft); }


/* ---------- calendar panel ---------- */
.tray-cal__nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; }
.tray-cal__arrow {
  width: 1.6rem; height: 1.6rem;
  border-radius: 8px;
  color: var(--text-soft);
  font-size: 1rem;
  line-height: 1;
}
.tray-cal__arrow:hover { background: var(--glass-hover); color: var(--text); }
.tray-cal__month { font-size: 0.82rem; font-weight: 700; }

.tray-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.15rem; }
.tray-cal__grid--head { margin-bottom: 0.2rem; }
.tray-cal__weekday {
  text-align: center;
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--brand);
  padding-bottom: 0.2rem;
}
.tray-cal__cell {
  aspect-ratio: 1;
  min-height: 0;
  display: grid;
  place-items: center;
  border-radius: 8px;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}
.tray-cal__cell.is-blank { visibility: hidden; }
.tray-cal__cell.is-weekend { color: var(--down); }
.tray-cal__cell.is-today {
  background: var(--brand);
  color: var(--brand-contrast);
  font-weight: 800;
}
.tray-cal__today {
  display: block;
  width: 100%;
  margin-top: 0.6rem;
  padding: 0.35rem;
  border-radius: 9px;
  font-size: 0.72rem;
  color: var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}

/* ---------- weather panel ---------- */
.tray-wx__head { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.35rem; }
.tray-wx__glyph svg { width: 3.2rem; height: 3.2rem; }
.tray-wx__temp { font-size: 1.9rem; font-weight: 800; line-height: 1.1; color: var(--text-strong); }
.tray-wx__desc { font-size: 0.76rem; color: var(--text-soft); }
.tray-wx__city { font-size: 0.74rem; color: var(--text-soft); margin-bottom: 0.6rem; }
.tray-wx__rows { display: flex; flex-direction: column; gap: 0.35rem; padding-top: 0.6rem; border-top: 1px solid var(--divider); }
.tray-wx__row { display: flex; justify-content: space-between; font-size: 0.76rem; }
.tray-wx__row b { font-weight: 700; }

@media (max-width: 640px) {
  .tray-panel { inset-inline: 1rem; width: auto; }
  #taskbar-tray { display: none; }
}

/* ---------- clock panel: local reference, then the session card ------ */
.tray-local {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  padding-bottom: 0.85rem;
  margin-bottom: 0.85rem;
  border-bottom: 1px solid var(--divider);
}
.tray-local__text { text-align: start; }
.tray-local__time {
  display: block;
  font-size: 1.55rem;
  font-weight: 800;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.tray-local__label { font-size: 0.7rem; color: var(--text-soft); }

.tray-face { width: 4.6rem; height: 4.6rem; flex-shrink: 0; }
.tray-face__disc {
  fill: rgba(255, 255, 255, 0.35);
  stroke: var(--divider);
  stroke-width: 1.5;
}
html.dark .tray-face__disc { fill: rgba(255, 255, 255, 0.05); }
.tray-face__tick { stroke: currentColor; stroke-width: 1.6; opacity: 0.3; stroke-linecap: round; }
.tray-face__tick.is-major { opacity: 0.6; stroke-width: 2.4; }
.tray-face__hour,
.tray-face__minute {
  stroke: var(--text-strong);
  stroke-linecap: round;
  stroke-width: 4;
  transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.tray-face__minute { stroke-width: 3; }
.tray-face__second {
  stroke: var(--down);
  stroke-width: 1.6;
  stroke-linecap: round;
  transition: transform 0.15s cubic-bezier(0.34, 1.5, 0.64, 1);
}
.tray-face__pin { fill: var(--down); }

/* The market-hours card, brought into the panel unchanged in spirit. */
.tray-status {
  padding: 0.35rem 0.7rem;
  margin-bottom: 0.75rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-soft);
  background: rgba(148, 163, 184, 0.16);
}
.tray-status.is-open { color: #15803d; background: rgba(34, 197, 94, 0.16); }
html.dark .tray-status.is-open { color: #4ade80; }

.tray-session {
  --session-tone: var(--brand);
  text-align: start;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.tray-session.is-in { opacity: 1; transform: none; }
.tray-session:not(.is-open) { filter: saturate(0.6); }

.tray-session__head { display: flex; align-items: center; gap: 0.45rem; font-size: 0.82rem; margin-bottom: 0.45rem; }
.tray-session__dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--session-tone); flex-shrink: 0; }
.tray-session.is-open .tray-session__dot {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--session-tone) 28%, transparent);
}
.tray-session__name { font-weight: 700; flex: 1; }
.tray-session__hours {
  font-size: 0.72rem;
  color: var(--text-soft);
  direction: ltr;
  unicode-bidi: isolate;
  font-variant-numeric: tabular-nums;
}
.tray-session__track { height: 0.32rem; border-radius: 999px; background: var(--divider); overflow: hidden; }
.tray-session__fill { height: 100%; border-radius: 999px; background: var(--session-tone); transition: width 0.6s ease; }
.tray-session__foot { display: flex; justify-content: space-between; margin-top: 0.35rem; }
.tray-session__note { font-size: 0.68rem; color: var(--text-soft); }
.tray-session__zone { font-size: 0.64rem; color: var(--text-soft); direction: ltr; }

.tray-dots { display: flex; justify-content: center; gap: 0.3rem; padding-top: 0.7rem; }
.tray-pip {
  width: 0.4rem; height: 0.4rem;
  border-radius: 999px;
  background: var(--divider);
  transition: width 0.25s var(--ease), background-color 0.25s var(--ease);
}
.tray-pip.is-active { width: 1.05rem; background: var(--brand); }

/* ---------- weather panel, centred ---------- */
.tray-wx__head { justify-content: center; }
.tray-wx__city { text-align: center; }
.tray-wx__rows { text-align: start; }

/* ==================================================================
   Desktop shortcuts
   Apps a visitor has pinned. Laid out in columns down the leading edge,
   under the cards so a shortcut never covers one.
   ================================================================== */
.shortcut-layer {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.shortcut {
  position: absolute;
  width: 76px;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.2rem;
  border-radius: 12px;
  border: 1px solid transparent;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.shortcut { cursor: grab; touch-action: none; }
.shortcut.is-dragging { cursor: grabbing; opacity: 0.85; transition: none; }
.shortcut:hover { background: rgba(255, 255, 255, 0.14); }
html.dark .shortcut:hover { background: rgba(255, 255, 255, 0.08); }
.shortcut.is-selected {
  background: rgba(255, 255, 255, 0.22);
  border-color: var(--glass-border);
}
html.dark .shortcut.is-selected { background: rgba(255, 255, 255, 0.12); }

.shortcut__icon {
  --tile-tint: var(--tile-accent, var(--brand));
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  border-radius: 13px;
  color: var(--tile-tint);
  background: color-mix(in srgb, var(--tile-tint) 16%, rgba(255, 255, 255, 0.35));
  border: 1px solid color-mix(in srgb, var(--tile-tint) 24%, transparent);
}
html.dark .shortcut__icon {
  background: color-mix(in srgb, var(--tile-tint) 22%, rgba(0, 0, 0, 0.25));
}
.shortcut__icon svg,
.shortcut__icon img { width: 1.6rem; height: 1.6rem; }

.shortcut__label {
  font-size: 0.68rem;
  line-height: 1.5;
  text-align: center;
  color: var(--text-strong);
  /* Two lines at most; a long app name should not push the next row. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
html.dark .shortcut__label { text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); }

#shortcut-menu { min-width: 11rem; }

/* Shortcuts are a pointer idea; on a phone the start menu is the way in. */
@media (max-width: 767px) {
  .shortcut-layer { display: none; }
}

/* ==================================================================
   Phones
   The cards already went full width, but the rest was still built for a
   pointer: targets under the 44px that fingers need, a taskbar competing
   with the home indicator, and hover-only affordances.
   ================================================================== */
@media (max-width: 767px) {
  /* Room for the taskbar plus the phone's own gesture area. */
  #desktop {
    padding-bottom: calc(6rem + env(safe-area-inset-bottom, 0px));
    padding-inline: 0.75rem;
  }

  .taskbar {
    padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
  }

  /* Every tap target reaches the 44px that fingers actually need. */
  .taskbar .icon-btn,
  .taskbar .notif-btn,
  .taskbar .lang-btn {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  .card__title { padding: 0.85rem 1rem; font-size: 0.92rem; }

  /* Start menu as a sheet rather than a floating panel: it is the main
     way around the site on a phone, so it gets the whole width. */
  #start-menu {
    inset-inline: 0.5rem;
    bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
    width: auto;
    max-height: 70vh;
    border-radius: 22px;
  }
  .app-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.1rem 0.75rem; }
  .app-tile { padding: 0.55rem 0.25rem; }
  .app-tile__name { font-size: 0.7rem; }

  /* Tabs scroll with momentum and keep a comfortable target height. */
  .tabs { gap: 0.25rem; }
  .tabs button { padding: 0.6rem 0.85rem; }

  /* Windows fill the screen — a draggable, resizable window is a pointer
     idea, and a half-screen one on a phone is just a smaller screen. */
  .window {
    inset: 0.75rem 0.75rem auto !important;
    width: auto !important;
    max-height: calc(100vh - 8rem);
  }
  .window__resize { display: none; }

  /* Popovers span the width instead of hugging one corner. */
  .popover { inset-inline: 0.75rem; width: auto; }

  /* Hover-only reveals never appear on touch, so they are always shown. */
  .widget .card__title { opacity: 1; }
}

/* Very small phones: two app columns rather than three. */
@media (max-width: 380px) {
  .app-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Context menu entries: an icon, a label, and a separator between the
   things that open something and the things that change the desktop. */
.menu__item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.5rem 0.75rem;
  border-radius: 9px;
  font-size: 0.8rem;
  text-align: start;
  color: var(--text);
  transition: background-color 0.14s ease, color 0.14s ease;
}
.menu__item:hover { background: var(--glass-hover); }
.menu__item svg { flex-shrink: 0; opacity: 0.75; }
.menu__item--danger { color: var(--down); }
.menu__item--danger:hover { background: color-mix(in srgb, var(--down) 12%, transparent); }
.menu__sep { height: 1px; margin: 0.3rem 0.4rem; background: var(--divider); }

/* The symbolic password types itself in; a caret while it does. */
#password-input[data-symbolic] {
  letter-spacing: 0.12em;
  font-family: ui-monospace, Menlo, monospace;
}
#password-input[data-symbolic]:not(.is-typed) {
  border-inline-end: 2px solid var(--brand);
  animation: caret-blink 0.9s step-end infinite;
}
@keyframes caret-blink {
  50% { border-inline-end-color: transparent; }
}

/* Rename box for a desktop shortcut. Centred rather than anchored to the
   icon, so it never lands off the edge of the screen. */
.rename {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3000;
  width: min(20rem, calc(100vw - 2rem));
  padding: 1.1rem;
  border-radius: 18px;
  box-shadow: var(--shadow-lg);
}
.rename__label { display: block; font-size: 0.78rem; font-weight: 600; margin-bottom: 0.5rem; }
.rename__input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: 10px;
  font-size: 0.85rem;
  color: var(--text);
  background: rgba(255, 255, 255, 0.55);
  border: 1.5px solid var(--divider);
}
html.dark .rename__input { background: rgba(255, 255, 255, 0.08); }
.rename__input:focus { outline: none; border-color: var(--brand); }
.rename__actions { display: flex; justify-content: flex-end; gap: 0.45rem; margin-top: 0.85rem; }
.rename__btn {
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--text-soft);
}
.rename__btn:hover { background: var(--glass-hover); color: var(--text); }
.rename__btn--primary { background: var(--brand); color: var(--brand-contrast); font-weight: 600; }
.rename__btn--primary:hover { background: var(--brand); filter: brightness(1.05); }

/* ==================================================================
   Windows grow from whatever opened them
   The origin is set in script to the centre of the icon that was
   clicked; without one it falls back to the middle of the window.
   ================================================================== */
.window {
  transform-origin: var(--origin-x, 50%) var(--origin-y, 50%);
}

@keyframes window-open {
  from { opacity: 0; transform: scale(0.55); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes window-close {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.55); }
}

.window.is-opening { animation: window-open 0.24s cubic-bezier(0.2, 0.9, 0.3, 1); }
.window.is-closing { animation: window-close 0.2s cubic-bezier(0.4, 0, 0.8, 0.4) forwards; }

@media (prefers-reduced-motion: reduce) {
  .window.is-opening, .window.is-closing { animation: none; }
}

/* ==================================================================
   Focus mode — dim everything except the card being read
   ================================================================== */
body.is-focusing .widget:not(.is-focused) {
  opacity: 0.25;
  filter: saturate(0.7);
  transition: opacity 0.25s var(--ease), filter 0.25s var(--ease);
}
body.is-focusing .widget.is-focused {
  transform: scale(1.02);
  transition: transform 0.25s var(--ease);
  z-index: 40;
}

/* ==================================================================
   Desktop shortcuts
   Apps a visitor has pinned. Laid out in columns down the leading edge,
   under the cards so a shortcut never covers one.
   ================================================================== */
.shortcut-layer {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.shortcut {
  position: absolute;
  width: 76px;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.2rem;
  border-radius: 12px;
  border: 1px solid transparent;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.shortcut { cursor: grab; touch-action: none; }
.shortcut.is-dragging { cursor: grabbing; opacity: 0.85; transition: none; }
.shortcut:hover { background: rgba(255, 255, 255, 0.14); }
html.dark .shortcut:hover { background: rgba(255, 255, 255, 0.08); }
.shortcut.is-selected {
  background: rgba(255, 255, 255, 0.22);
  border-color: var(--glass-border);
}
html.dark .shortcut.is-selected { background: rgba(255, 255, 255, 0.12); }

.shortcut__icon {
  --tile-tint: var(--tile-accent, var(--brand));
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  border-radius: 13px;
  color: var(--tile-tint);
  background: color-mix(in srgb, var(--tile-tint) 16%, rgba(255, 255, 255, 0.35));
  border: 1px solid color-mix(in srgb, var(--tile-tint) 24%, transparent);
}
html.dark .shortcut__icon {
  background: color-mix(in srgb, var(--tile-tint) 22%, rgba(0, 0, 0, 0.25));
}
.shortcut__icon svg,
.shortcut__icon img { width: 1.6rem; height: 1.6rem; }

.shortcut__label {
  font-size: 0.68rem;
  line-height: 1.5;
  text-align: center;
  color: var(--text-strong);
  /* Two lines at most; a long app name should not push the next row. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
html.dark .shortcut__label { text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); }

#shortcut-menu { min-width: 11rem; }

/* Shortcuts are a pointer idea; on a phone the start menu is the way in. */
@media (max-width: 767px) {
  .shortcut-layer { display: none; }
}

/* ==================================================================
   Phones
   The cards already went full width, but the rest was still built for a
   pointer: targets under the 44px that fingers need, a taskbar competing
   with the home indicator, and hover-only affordances.
   ================================================================== */
@media (max-width: 767px) {
  /* Room for the taskbar plus the phone's own gesture area. */
  #desktop {
    padding-bottom: calc(6rem + env(safe-area-inset-bottom, 0px));
    padding-inline: 0.75rem;
  }

  .taskbar {
    padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
  }

  /* Every tap target reaches the 44px that fingers actually need. */
  .taskbar .icon-btn,
  .taskbar .notif-btn,
  .taskbar .lang-btn {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  .card__title { padding: 0.85rem 1rem; font-size: 0.92rem; }

  /* Start menu as a sheet rather than a floating panel: it is the main
     way around the site on a phone, so it gets the whole width. */
  #start-menu {
    inset-inline: 0.5rem;
    bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
    width: auto;
    max-height: 70vh;
    border-radius: 22px;
  }
  .app-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.1rem 0.75rem; }
  .app-tile { padding: 0.55rem 0.25rem; }
  .app-tile__name { font-size: 0.7rem; }

  /* Tabs scroll with momentum and keep a comfortable target height. */
  .tabs { gap: 0.25rem; }
  .tabs button { padding: 0.6rem 0.85rem; }

  /* Windows fill the screen — a draggable, resizable window is a pointer
     idea, and a half-screen one on a phone is just a smaller screen. */
  .window {
    inset: 0.75rem 0.75rem auto !important;
    width: auto !important;
    max-height: calc(100vh - 8rem);
  }
  .window__resize { display: none; }

  /* Popovers span the width instead of hugging one corner. */
  .popover { inset-inline: 0.75rem; width: auto; }

  /* Hover-only reveals never appear on touch, so they are always shown. */
  .widget .card__title { opacity: 1; }
}

/* Very small phones: two app columns rather than three. */
@media (max-width: 380px) {
  .app-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Context menu entries: an icon, a label, and a separator between the
   things that open something and the things that change the desktop. */
.menu__item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.5rem 0.75rem;
  border-radius: 9px;
  font-size: 0.8rem;
  text-align: start;
  color: var(--text);
  transition: background-color 0.14s ease, color 0.14s ease;
}
.menu__item:hover { background: var(--glass-hover); }
.menu__item svg { flex-shrink: 0; opacity: 0.75; }
.menu__item--danger { color: var(--down); }
.menu__item--danger:hover { background: color-mix(in srgb, var(--down) 12%, transparent); }
.menu__sep { height: 1px; margin: 0.3rem 0.4rem; background: var(--divider); }

/* The symbolic password types itself in; a caret while it does. */
#password-input[data-symbolic] {
  letter-spacing: 0.12em;
  font-family: ui-monospace, Menlo, monospace;
}
#password-input[data-symbolic]:not(.is-typed) {
  border-inline-end: 2px solid var(--brand);
  animation: caret-blink 0.9s step-end infinite;
}
@keyframes caret-blink {
  50% { border-inline-end-color: transparent; }
}

/* Rename box for a desktop shortcut. Centred rather than anchored to the
   icon, so it never lands off the edge of the screen. */
.rename {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3000;
  width: min(20rem, calc(100vw - 2rem));
  padding: 1.1rem;
  border-radius: 18px;
  box-shadow: var(--shadow-lg);
}
.rename__label { display: block; font-size: 0.78rem; font-weight: 600; margin-bottom: 0.5rem; }
.rename__input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: 10px;
  font-size: 0.85rem;
  color: var(--text);
  background: rgba(255, 255, 255, 0.55);
  border: 1.5px solid var(--divider);
}
html.dark .rename__input { background: rgba(255, 255, 255, 0.08); }
.rename__input:focus { outline: none; border-color: var(--brand); }
.rename__actions { display: flex; justify-content: flex-end; gap: 0.45rem; margin-top: 0.85rem; }
.rename__btn {
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--text-soft);
}
.rename__btn:hover { background: var(--glass-hover); color: var(--text); }
.rename__btn--primary { background: var(--brand); color: var(--brand-contrast); font-weight: 600; }
.rename__btn--primary:hover { background: var(--brand); filter: brightness(1.05); }

/* ==================================================================
   Windows grow from whatever opened them
   The origin is set in script to the centre of the icon that was
   clicked; without one it falls back to the middle of the window.
   ================================================================== */
.window {
  transform-origin: var(--origin-x, 50%) var(--origin-y, 50%);
}

@keyframes window-open {
  from { opacity: 0; transform: scale(0.55); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes window-close {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.55); }
}

.window.is-opening { animation: window-open 0.24s cubic-bezier(0.2, 0.9, 0.3, 1); }
.window.is-closing { animation: window-close 0.2s cubic-bezier(0.4, 0, 0.8, 0.4) forwards; }

@media (prefers-reduced-motion: reduce) {
  .window.is-opening, .window.is-closing { animation: none; }
}

/* ==================================================================
   Focus mode — dim everything except the card being read
   ================================================================== */
body.is-focusing .widget:not(.is-focused) {
  opacity: 0.25;
  filter: saturate(0.7);
  transition: opacity 0.25s var(--ease), filter 0.25s var(--ease);
}
body.is-focusing .widget.is-focused {
  transform: scale(1.02);
  transition: transform 0.25s var(--ease);
  z-index: 40;
}

/* The start menu while a context menu is open over it: still visible, so
   the app being acted on stays in view, but clearly not the active layer. */
#start-menu.is-behind-menu {
  filter: blur(3px) saturate(0.85);
  opacity: 0.65;
  pointer-events: none;
  transition: filter 0.18s var(--ease), opacity 0.18s var(--ease);
}

/* ==================================================================
   Ambient layer — a tint over the wallpaper that follows the hour
   Sits above the wallpaper and below everything else, so the chosen
   image still shows through.
   ================================================================== */
#ambient-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: soft-light;
  transition: background 8s linear, opacity 2s linear;
}

@media (prefers-reduced-motion: reduce) {
  #ambient-layer { transition: none; }
}
