/* =========================================================
   سامانه ثبت اطلاعات علمی — Stylesheet
   Refined dark glassmorphism, RTL-first
   ========================================================= */

/* ---------- Design tokens ---------- */
:root {
  /* palette — taken from the club emblem (bright #20ea04 -> deep #123a02) */
  --bg-0:        #071a10;
  --bg-1:        #0d2717;

  --accent:      #5cd63a;   /* readable bright green for accents and focus */
  --accent-2:    #2f9e18;   /* mid green */
  --accent-3:    #1d6b0c;   /* deep green */
  --on-accent:   #06170b;   /* text that sits on an accent fill */
  --danger:      #fb7185;
  --success:     #34d399;

  /* glass surfaces */
  --glass-card:  linear-gradient(150deg, rgba(255,255,255,.10), rgba(255,255,255,.025) 55%, rgba(255,255,255,.055));
  --glass-panel: rgba(0,0,0,.16);
  --glass-input: rgba(0,0,0,.24);
  --glass-input-hover: rgba(0,0,0,.30);

  --stroke:      rgba(255,255,255,.13);
  --stroke-soft: rgba(255,255,255,.09);
  --stroke-strong: rgba(255,255,255,.18);

  /* text */
  --text:        #edf6ea;
  --text-soft:   #b4c9ae;
  --text-dim:    #7d9078;

  /* radii */
  --r-xs: 10px;
  --r-sm: 14px;
  --r-md: 18px;
  --r-lg: 26px;
  --r-xl: 34px;

  /* shadows */
  --sh-card:  0 40px 90px -30px rgba(0,0,0,.85), 0 0 0 1px rgba(255,255,255,.05);
  --sh-panel: 0 18px 40px -24px rgba(0,0,0,.7);
  --sh-btn:   0 16px 34px -16px rgba(67,181,38,.45);

  --ring: 0 0 0 3px rgba(92,214,58,.28);

  --ease: cubic-bezier(.22,.61,.36,1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;

  /* The canvas colour. Never visible while the page is still — the fixed
     .aurora layer covers it — but it is what the compositor shows in tiles it
     has not rasterised yet during a fast fling. It used to be the darkest stop
     in the palette, which is why a dark box flashed at the bottom of a quick
     scroll. These stops are sampled from the rendered page at six depths, so
     an un-painted band now matches its surroundings instead of contrasting.
     Set on html rather than body because body has overflow-x: hidden, which
     can stop background propagation to the canvas. */
  background: linear-gradient(180deg,
    #305938 8%, #2a4b30 25%, #28482e 42%,
    #2f5035 58%, #2d4e34 75%, #305933 92%);
}

body {
  margin: 0;
  min-height: 100dvh;
  font-family: "Vazirmatn", system-ui, "Segoe UI", Tahoma, sans-serif;
  font-size: 16px;
  line-height: 1.75;
  color: var(--text);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;

  overscroll-behavior-y: contain;
}

h1, h2, h3, p, figure { margin: 0; }
img { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: rgba(92,214,58,.32); }

/* Firefox + WebKit scrollbar */
* { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.18) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.15);
  border-radius: 20px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.28); background-clip: content-box; }

/* ---------- Accessibility helpers ---------- */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed;
  inset-inline-start: 50%;
  top: -100px;
  transform: translateX(50%);
  z-index: 999;
  padding: 12px 24px;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  text-decoration: none;
  transition: top .25s var(--ease);
}
.skip-link:focus-visible { top: 0; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* =========================================================
   Background
   ========================================================= */
.aurora {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(1100px 620px at 82% -8%,  rgba(126,224,90,.13), transparent 62%),
    radial-gradient(980px  680px at 8%  102%, rgba(58,178,34,.16), transparent 60%),
    linear-gradient(165deg, #0a2314 0%, #133620 40%, #0c2616 72%, #071b0f 100%);
}

/* The orbs used to be radial gradients with an extra filter: blur(110px) on
   top, animated with translate + scale. The scale forced the browser to
   re-rasterise a 48vmax blurred texture on every single frame — that alone
   took mobile scrolling from 60fps to about 9fps. A radial gradient is
   already soft, so the blur was close to redundant: it is gone, and the
   drift is now translate-only, which the compositor handles for free. */
.orb {
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
}
.orb-1 {
  width: 62vmax; height: 62vmax;
  background: radial-gradient(closest-side circle,
    rgba(120,222,84,.20) 0%, rgba(120,222,84,.11) 34%, rgba(120,222,84,.03) 62%, transparent 78%);
  top: -22vmax; inset-inline-end: -20vmax;
  animation: drift-a 26s var(--ease) infinite alternate;
}
.orb-2 {
  width: 70vmax; height: 70vmax;
  background: radial-gradient(closest-side circle,
    rgba(46,158,26,.24) 0%, rgba(46,158,26,.13) 34%, rgba(46,158,26,.04) 62%, transparent 78%);
  bottom: -30vmax; inset-inline-start: -24vmax;
  animation: drift-b 32s var(--ease) infinite alternate;
}
.orb-3 {
  width: 46vmax; height: 46vmax;
  background: radial-gradient(closest-side circle,
    rgba(32,140,44,.19) 0%, rgba(32,140,44,.10) 36%, rgba(32,140,44,.03) 64%, transparent 80%);
  top: 38%; inset-inline-start: 40%;
  animation: drift-c 24s var(--ease) infinite alternate;
}

/* translate only — a scale() here would force a repaint every frame */
@keyframes drift-a { to { transform: translate3d(-6vmax,  5vmax, 0); } }
@keyframes drift-b { to { transform: translate3d( 7vmax, -6vmax, 0); } }
@keyframes drift-c { to { transform: translate3d(-5vmax, -7vmax, 0); } }

/* subtle film grain so the gradients don't band */
.grain {
  position: absolute;
  inset: 0;
  opacity: .16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* =========================================================
   Layout
   ========================================================= */
.page {
  position: relative;
  z-index: 1;
  padding: clamp(20px, 5vw, 68px) clamp(14px, 4vw, 32px) 48px;
}

.card {
  max-width: 1080px;
  margin-inline: auto;
  padding: clamp(24px, 4.5vw, 56px);
  border-radius: clamp(24px, 3.6vw, 40px);
  background: var(--glass-card);
  border: 1px solid var(--stroke);
  box-shadow: var(--sh-card);
  backdrop-filter: blur(28px) saturate(150%);
  -webkit-backdrop-filter: blur(28px) saturate(150%);
  position: relative;
  overflow: hidden;
  animation: rise .8s var(--ease) both;
}

/* top highlight edge */
.card::before {
  content: "";
  position: absolute;
  inset-inline: 12%;
  top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.5), transparent);
  pointer-events: none;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================
   Masthead
   ========================================================= */
.masthead {
  text-align: center;
  padding-bottom: clamp(24px, 3vw, 38px);
  margin-bottom: clamp(24px, 3vw, 38px);
  border-bottom: 1px solid var(--stroke-soft);
}

.brand-mark {
  position: relative;
  width: 108px; height: 108px;
  margin-inline: auto;
  display: grid; place-items: center;
}

/* No pool behind the mark. Separation comes from shadows that follow the
   emblem's own outline: a tight dark edge hugging each stroke for contrast,
   then a soft green glow further out for life. Both track the alpha shape,
   so there is no disc sitting behind the logo. */
.brand-mark img {
  position: relative;
  width: 100%; height: 100%;
  object-fit: contain;
  filter:
    drop-shadow(0 0 2px rgba(0,0,0,.65))
    drop-shadow(0 1px 4px rgba(0,0,0,.45))
    drop-shadow(0 0 18px rgba(96,208,64,.30));
}

.eyebrow {
  margin-top: 20px;
  max-width: 52ch;
  margin-inline: auto;
  line-height: 1.9;
  text-wrap: balance;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .06em;
  color: var(--accent);
  text-transform: none;
}

.masthead h1 {
  margin-top: 8px;
  font-size: clamp(1.55rem, 4.2vw, 2.5rem);
  font-weight: 800;
  line-height: 1.35;
  letter-spacing: -.01em;
  background: linear-gradient(180deg, #ffffff, #b6dfa8);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.lede {
  margin-top: 12px;
  margin-inline: auto;
  max-width: 54ch;
  color: var(--text-soft);
  font-size: clamp(.92rem, 2.3vw, 1rem);
  font-weight: 300;
}

/* ---------- Progress ---------- */
.progress { margin-top: 28px; max-width: 460px; margin-inline: auto; }

.progress-head {
  display: flex;
  justify-content: space-between;
  font-size: .8rem;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.progress-value { color: var(--accent); font-weight: 700; font-variant-numeric: tabular-nums; }

.progress-track {
  height: 7px;
  border-radius: 99px;
  background: rgba(0,0,0,.28);
  overflow: hidden;
  border: 1px solid var(--stroke-soft);
}
.progress-bar {
  height: 100%;
  width: 0%;
  border-radius: 99px;
  background: linear-gradient(90deg, #6fd94a, #3aa81e 75%, #2a8515);
  box-shadow: 0 0 12px rgba(92,214,58,.35);
  transition: width .5s var(--ease);
}

/* =========================================================
   Panels — "liquid glass"
   Three things carry the effect, all static:
     1. a heavily blurred + saturated backdrop (the lens body)
     2. a specular rim, brighter at the corners light would catch
     3. an inner bevel — highlight on top, shade at the bottom — for thickness
   The highlight sits fixed at the upper-left; nothing tracks the cursor.
   ========================================================= */

.panel {
  position: relative;
  z-index: 1;
  border: none;
  border-radius: 30px;
  padding: clamp(20px, 3vw, 32px);
  margin-bottom: 22px;

  /* 1 — lens body. The sheen is a background layer so it stays under the text. */
  background:
    radial-gradient(52% 64% at 22% -8%,
      rgba(255,255,255,.055), rgba(255,255,255,.018) 42%, transparent 72%),
    linear-gradient(150deg,
      rgba(255,255,255,.06) 0%, rgba(255,255,255,.012) 46%, rgba(255,255,255,.035) 100%),
    rgba(0,0,0,.16);

  backdrop-filter: blur(26px) saturate(185%) brightness(1.05);
  -webkit-backdrop-filter: blur(26px) saturate(185%) brightness(1.05);

  /* 3 — bevel: rim light on top, shade pooling at the bottom */
  box-shadow:
    inset 0  1px  1px rgba(255,255,255,.16),
    inset 0 22px 34px -30px rgba(255,255,255,.28),
    inset 0 -14px 28px -20px rgba(0,0,0,.55),
    0 20px 44px -24px rgba(0,0,0,.66),
    0 2px 8px -5px rgba(0,0,0,.5);

  transition: box-shadow .4s var(--ease);
}

/* 2 — the refractive rim: a 1px gradient border, brightest at the two
   corners the light favours. mask-composite punches out the middle. */
.panel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(150deg,
    rgba(255,255,255,.34) 0%,
    rgba(255,255,255,.10) 20%,
    rgba(255,255,255,.04) 48%,
    rgba(255,255,255,.11) 76%,
    rgba(255,255,255,.27) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

.panel:focus-within::before {
  background: linear-gradient(150deg,
    rgba(168,255,132,.42) 0%,
    rgba(146,255,110,.13) 20%,
    rgba(255,255,255,.05) 48%,
    rgba(146,255,110,.14) 76%,
    rgba(168,255,132,.34) 100%);
}

/* while its date popover is open, this panel must paint above the ones after it */
.panel.is-raised { z-index: 60; }

.panel-head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 26px;
}

.step {
  flex: none;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 13px;
  font-size: 1rem;
  font-weight: 700;
  color: #dcffd0;
  background: linear-gradient(145deg, rgba(92,214,58,.26), rgba(47,158,24,.14));
  border: 1px solid rgba(255,255,255,.16);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28);
}

.panel h2 {
  font-size: clamp(1.05rem, 2.6vw, 1.22rem);
  font-weight: 700;
  line-height: 1.5;
}
.panel-sub {
  font-size: .82rem;
  color: var(--text-dim);
  font-weight: 300;
  line-height: 1.6;
}

/* =========================================================
   Fields
   ========================================================= */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px 20px;
}

.field { min-width: 0; }
.field-full { margin-top: 20px; }

label {
  display: block;
  margin-bottom: 8px;
  font-size: .84rem;
  font-weight: 500;
  color: var(--text-soft);
}
.req { color: var(--accent); margin-inline-start: 2px; }

input[type="text"], input[type="tel"], select, textarea {
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--stroke);
  background: var(--glass-input);
  color: var(--text);
  outline: none;
  transition: background .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease);
}

input::placeholder, textarea::placeholder {
  color: var(--text-dim);
  opacity: .92;
  font-weight: 300;
}

input:hover, select:hover, textarea:hover { background: var(--glass-input-hover); }

input:focus, select:focus, textarea:focus {
  background: rgba(0,0,0,.30);
  border-color: rgba(92,214,58,.55);
  box-shadow: var(--ring);
}

textarea { resize: vertical; min-height: 120px; line-height: 1.85; }

/* numeric fields read better LTR-in-RTL */
input[inputmode="numeric"] {
  direction: ltr;
  text-align: end;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
}

/* The LTR direction above is right for the digits the user types, but it also
   reorders a Persian placeholder — "۱۰ رقم بدون خط تیره" rendered with the ۱۰
   thrown to the far end. While the placeholder is showing there are no digits
   to order, so hand the field back to RTL until something is typed. */
input[inputmode="numeric"]:placeholder-shown {
  direction: rtl;
  text-align: start;
  letter-spacing: normal;
}

/* select */
.select-wrap { position: relative; }
.select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-start: 42px;
  cursor: pointer;
}
.select-arrow {
  position: absolute;
  inset-inline-start: 16px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px; height: 17px;
  color: var(--text-dim);
  pointer-events: none;
}
select option { background: #0c1a10; color: var(--text); }
select:invalid, select:has(option[value=""]:checked) { color: var(--text-dim); }

/* hints, counters, errors */
.hint {
  margin-top: 6px;
  font-size: .74rem;
  color: var(--text-dim);
  font-weight: 300;
}
.field-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.counter {
  margin-top: 6px;
  font-size: .74rem;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.counter.is-near { color: #fbbf24; }

.error {
  margin-top: 6px;
  font-size: .76rem;
  color: var(--danger);
  min-height: 0;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height .25s var(--ease), opacity .25s var(--ease), margin .25s var(--ease);
}
.error.is-shown { max-height: 60px; opacity: 1; }

/* invalid / valid states */
.field.has-error input,
.field.has-error select,
.field.has-error textarea,
.has-error .date-input {
  border-color: rgba(251,113,133,.65);
  background: rgba(251,113,133,.07);
}
.field.has-error input:focus,
.field.has-error textarea:focus,
.field.has-error select:focus {
  box-shadow: 0 0 0 3px rgba(251,113,133,.22);
}

.field.is-valid input,
.field.is-valid select,
.field.is-valid textarea { border-color: rgba(52,211,153,.42); }

@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  30%, 70% { transform: translateX(3px); }
  50%      { transform: translateX(-3px); }
}
.field.shake { animation: shake .4s var(--ease); }

/* =========================================================
   Date picker
   ========================================================= */
.datepicker { position: relative; }

.date-input {
  display: flex;
  align-items: stretch;
  gap: 8px;
  border-radius: var(--r-md);
  transition: border-color .25s var(--ease);
}
.date-input input { flex: 1; }

.icon-btn {
  flex: none;
  width: 52px;
  display: grid; place-items: center;
  border-radius: var(--r-md);
  border: 1px solid var(--stroke);
  background: rgba(0,0,0,.24);
  color: var(--text-soft);
  cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease), transform .18s var(--ease);
}
.icon-btn svg { width: 19px; height: 19px; }
.icon-btn:hover { background: rgba(92,214,58,.18); color: #fff; }
.icon-btn:active { transform: scale(.94); }
.icon-btn[aria-expanded="true"] { background: rgba(92,214,58,.24); color: #fff; }

.calendar {
  position: absolute;
  z-index: 40;
  top: calc(100% + 10px);
  inset-inline-start: 0;
  width: min(330px, calc(100vw - 48px));
  padding: 16px;
  border-radius: var(--r-lg);
  background: rgba(7, 22, 12, .985);
  border: 1px solid var(--stroke-strong);
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.9);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  animation: pop .22s var(--ease) both;
}
.calendar[hidden] { display: none; }

@keyframes pop {
  from { opacity: 0; transform: translateY(-8px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
}
.cal-nav {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid var(--stroke);
  border-radius: 11px;
  background: rgba(255,255,255,.05);
  color: var(--text-soft);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.cal-nav:hover { background: rgba(92,214,58,.2); color: #fff; }

.cal-selects { display: flex; gap: 6px; flex: 1; }
.cal-selects select {
  padding: 7px 8px;
  font-size: .82rem;
  border-radius: 11px;
  background: rgba(255,255,255,.06);
  cursor: pointer;
  text-align: center;
  text-align-last: center;
}

.cal-weekdays, .cal-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.cal-weekdays {
  margin-bottom: 6px;
  font-size: .68rem;
  color: var(--text-dim);
  text-align: center;
}
.cal-weekdays span { padding: 4px 0; }

.cal-day {
  aspect-ratio: 1;
  min-height: 34px;
  border: 1px solid transparent;
  border-radius: 11px;
  background: rgba(255,255,255,.045);
  color: var(--text);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background .16s var(--ease), color .16s var(--ease), transform .16s var(--ease);
}
.cal-day:hover { background: rgba(92,214,58,.24); transform: translateY(-1px); }
.cal-day.is-empty { background: none; cursor: default; pointer-events: none; }
.cal-day.is-today { border-color: rgba(92,214,58,.6); color: var(--accent); font-weight: 700; }
.cal-day.is-selected {
  background: linear-gradient(145deg, #6fd94a, #3aa81e);
  color: var(--on-accent);
  font-weight: 700;
  border-color: transparent;
}
.cal-day.is-future { opacity: .3; cursor: not-allowed; pointer-events: none; }

.cal-foot {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--stroke-soft);
}
.cal-foot button {
  flex: 1;
  padding: 8px;
  font-size: .78rem;
  border-radius: 11px;
  border: 1px solid var(--stroke);
  background: rgba(255,255,255,.05);
  color: var(--text-soft);
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.cal-foot button:hover { background: rgba(92,214,58,.2); color: #fff; }

/* =========================================================
   Upload
   ========================================================= */
.upload-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  align-items: start;
}
@media (min-width: 720px) {
  .upload-row:has(.preview-box:not([hidden]))
    { grid-template-columns: 1fr minmax(180px, 220px); }
}

.dropzone {
  display: grid;
  place-items: center;
  min-height: 190px;
  padding: 28px 20px;
  text-align: center;
  border-radius: var(--r-lg);
  border: 1.5px dashed rgba(255,255,255,.22);
  background: rgba(0,0,0,.18);
  cursor: pointer;
  transition: border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease);
}
.dropzone:hover, .dropzone:focus-visible {
  border-color: rgba(92,214,58,.6);
  background: rgba(92,214,58,.08);
}
.dropzone.is-dragging {
  border-color: var(--accent);
  background: rgba(92,214,58,.14);
  transform: scale(1.01);
}
.dropzone.has-file { border-style: solid; border-color: rgba(52,211,153,.45); background: rgba(52,211,153,.06); }

.dz-icon { width: 34px; height: 34px; color: var(--accent); margin-inline: auto; }
.dz-title { margin-top: 12px; font-weight: 600; font-size: .95rem; }
.dz-sub { margin-top: 4px; font-size: .76rem; color: var(--text-dim); font-weight: 300; }

.preview-box {
  display: grid;
  gap: 10px;
  justify-items: center;
  padding: 14px;
  border-radius: var(--r-lg);
  background: rgba(0,0,0,.18);
  border: 1px solid var(--stroke);
  animation: pop .3s var(--ease) both;
}
.preview-box[hidden] { display: none; }
#preview {
  width: 100%;
  max-width: 170px;
  aspect-ratio: 3/4;
  object-fit: cover;
  border-radius: var(--r-md);
  border: 1px solid rgba(255,255,255,.22);
}
.preview-name {
  font-size: .72rem;
  color: var(--text-dim);
  text-align: center;
  word-break: break-all;
  direction: ltr;
}
.ghost-btn {
  padding: 7px 16px;
  font-size: .76rem;
  border-radius: 99px;
  border: 1px solid rgba(251,113,133,.4);
  background: rgba(251,113,133,.1);
  color: #ffc2cc;
  cursor: pointer;
  transition: background .2s var(--ease);
}
.ghost-btn:hover { background: rgba(251,113,133,.22); }

/* =========================================================
   Submit
   ========================================================= */
.submit-area { margin-top: 30px; text-align: center; }

.form-alert {
  margin-bottom: 16px;
  padding: 13px 18px;
  border-radius: var(--r-md);
  background: rgba(251,113,133,.12);
  border: 1px solid rgba(251,113,133,.35);
  color: #ffc2cc;
  font-size: .86rem;
  animation: pop .25s var(--ease) both;
}
.form-alert[hidden] { display: none; }

.submit-btn {
  position: relative;
  width: 100%;
  padding: 17px 28px;
  border: none;
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, #6fd94a 0%, #43b526 52%, #35a01c 100%);
  background-size: 200% 200%;
  color: var(--on-accent);
  font-size: 1.05rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: var(--sh-btn);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), background-position .5s var(--ease);
  overflow: hidden;
}
.submit-btn:hover {
  transform: translateY(-2px);
  background-position: 100% 50%;
  box-shadow: 0 22px 44px -16px rgba(67,181,38,.5);
}
.submit-btn:active { transform: translateY(0); }
.submit-btn[disabled] { cursor: progress; opacity: .85; transform: none; }

/* shine sweep */
.submit-btn::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  inset-inline-start: -60%;
  width: 45%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
  transform: skewX(-20deg);
  transition: inset-inline-start .7s var(--ease);
}
.submit-btn:hover::after { inset-inline-start: 120%; }

.spinner {
  display: none;
  width: 18px; height: 18px;
  margin-inline-start: 10px;
  vertical-align: -3px;
  border: 2.5px solid rgba(6,23,11,.30);
  border-top-color: var(--on-accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
.submit-btn.is-loading .spinner { display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }

.fineprint {
  margin-top: 14px;
  font-size: .74rem;
  color: var(--text-dim);
  font-weight: 300;
}

.site-foot {
  margin-top: 32px;
  text-align: center;
  font-size: .76rem;
  color: var(--text-dim);
  font-weight: 300;
}

/* =========================================================
   Responsive
   ========================================================= */
/* =========================================================
   Phones — cheap rendering, same picture
   backdrop-filter is the most expensive thing a mobile GPU can be asked to do
   while scrolling, and here it blurs a smooth gradient — there is almost no
   detail behind these surfaces for it to blur. So it comes off, along with the
   masked gradient rims and the heavier shadows.

   What it *was* also doing was saturate(185%) brightness(1.06), and that is a
   real colour change, not just a blur. A plain white veil washes the green out,
   so the fills below use a green-tinted veil instead, tuned against screenshots
   of the blurred version: mean difference 2.4/255, invisible in practice.

   The orbs and the grain stay — static, no filter, they rasterise once. Hiding
   the grain was tried and rejected: it lifts the page ~14/255, and without it
   everything looked noticeably darker.
   ========================================================= */
@media (max-width: 768px) {
  body { font-size: 15px; }

  .orb { animation: none; will-change: auto; }

  .card, .panel, .calendar, .icon-btn, input, select, textarea {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  .card {
    background: linear-gradient(150deg,
      rgba(150,255,165,.125) 0%, rgba(120,225,135,.0275) 52%, rgba(140,245,155,.0688) 100%);
    box-shadow: 0 20px 50px -28px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.05);
  }

  /* the rim was a masked gradient border — an extra compositing pass per panel */
  .panel::before { display: none; }
  .panel {
    border: 1px solid rgba(255,255,255,.14);
    border-radius: var(--r-lg);
    background:
      radial-gradient(52% 64% at 22% -8%, rgba(210,255,215,.05), rgba(210,255,215,.016) 42%, transparent 72%),
      linear-gradient(150deg, rgba(190,255,200,.135) 0%, rgba(190,255,200,.027) 46%, rgba(190,255,200,.081) 100%),
      rgba(0,0,0,.16);
    box-shadow:
      inset 0 1px 1px rgba(255,255,255,.14),
      0 12px 28px -18px rgba(0,0,0,.6);
  }
  /* without this the desktop rule would repaint the panel on focus and the
     colour would visibly jump */
  .panel:focus-within {
    border-color: rgba(146,255,110,.34);
    background:
      radial-gradient(52% 64% at 22% -8%, rgba(190,255,170,.06), rgba(210,255,215,.018) 42%, transparent 72%),
      linear-gradient(150deg, rgba(190,255,200,.145) 0%, rgba(190,255,200,.03) 46%, rgba(190,255,200,.088) 100%),
      rgba(0,0,0,.15);
  }

  input, select, textarea {
    background: linear-gradient(rgba(190,255,200,.105), rgba(190,255,200,.105)), rgba(0,0,0,.24);
  }
  input:hover, select:hover, textarea:hover,
  input:focus, select:focus, textarea:focus {
    background: linear-gradient(rgba(190,255,200,.13), rgba(190,255,200,.13)), rgba(0,0,0,.30);
  }
  .field.has-error input,
  .field.has-error select,
  .field.has-error textarea {
    background: linear-gradient(rgba(251,113,133,.10), rgba(251,113,133,.10)), rgba(0,0,0,.22);
  }

  .panel-head { gap: 11px; margin-bottom: 20px; }
  .step { width: 33px; height: 33px; font-size: .9rem; border-radius: 11px; }
  .grid { grid-template-columns: 1fr; }
  .calendar { inset-inline-start: 50%; transform: translateX(50%); }
  @keyframes pop {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
}

/* people who ask for less transparency get the cheap path too */
@media (prefers-reduced-transparency: reduce) {
  .card, .panel, .calendar, input, select, textarea {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}

/* =========================================================
   Motion / contrast preferences
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (prefers-contrast: more) {
  :root {
    --text-soft: #d8ecd2;
    --text-dim:  #a9c0a2;
    --stroke:    rgba(255,255,255,.30);
  }
}

/* Fallback when backdrop-filter is unsupported (older Firefox) */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .card     { background: #16351f; }
  .panel    { background: #102a19; box-shadow: inset 0 1px 0 rgba(255,255,255,.18); }
  .calendar { background: #0a1a10; }
}

@media print {
  .aurora, .skip-link, .submit-area, .site-foot { display: none !important; }
  body { background: #fff; color: #000; }
  .card, .panel { background: none; border-color: #ccc; box-shadow: none; }
}

/* ---------- Upload error state (dropzone lives outside .field) ---------- */
.upload-row.has-error .dropzone {
  border-color: rgba(251,113,133,.65);
  background: rgba(251,113,133,.07);
}
.upload-row.has-error .dz-icon { color: var(--danger); }
.upload-row.shake { animation: shake .4s var(--ease); }

/* ---------- A field that shouldn't stretch across a whole row ---------- */
.field-compact { max-width: 340px; }
@media (max-width: 640px) { .field-compact { max-width: none; } }
