repos
/ status-rust master

status-rust

mirror archived upstream

Single-binary self-hosted uptime monitoring and status pages on Rust axum: HTTP probes, Lighthouse audits, SEO crawler, and PDF reports.

axumdockerrustself-hostedsqlitestatus-pageuptime-monitoringvite

19.7 KB · 913 lines · SCSS Raw History
  1@use "variables" as *;
  2
  3// ── CSS variable overrides ──
  4// Bootstrap 5.3 writes defaults into `:root,[data-bs-theme=light]`. Use
  5// `html:root` so we outrank the default block and enforce the dark palette.
  6html:root {
  7  --bs-body-bg: #{$body-bg};
  8  --bs-body-color: #{$body-color};
  9  --bs-body-bg-rgb: 14, 13, 10;
 10  --bs-body-color-rgb: 221, 215, 205;
 11  --bs-emphasis-color: #{$white};
 12  --bs-secondary-bg: #13120e;
 13  --bs-tertiary-bg: #18160f;
 14  --bs-border-color: rgba(107, 158, 120, 0.12);
 15  --bs-link-color-rgb: 125, 184, 140;
 16  --bs-link-hover-color-rgb: 149, 204, 162;
 17  --bs-heading-color: #{$white};
 18}
 19
 20// ── Global ──
 21
 22body {
 23  min-height: 100vh;
 24  display: flex;
 25  flex-direction: column;
 26  -webkit-font-smoothing: antialiased;
 27  -moz-osx-font-smoothing: grayscale;
 28  letter-spacing: 0.01em;
 29  background-color: $body-bg !important;
 30  color: $body-color;
 31}
 32
 33main { flex: 1; }
 34
 35.vh-100 { height: 100vh; }
 36
 37// ── Logo (uptime-bars mark) ──
 38// Rendered as an inline SVG in the template so it scales cleanly. Matches the
 39// favicon exactly.
 40
 41.logo {
 42  display: inline-flex;
 43  align-items: center;
 44  justify-content: center;
 45  width: 28px;
 46  height: 28px;
 47  text-decoration: none !important;
 48  transition: transform 250ms ease;
 49
 50  svg {
 51    width: 100%;
 52    height: 100%;
 53    display: block;
 54  }
 55
 56  &:hover {
 57    transform: translateY(-1px);
 58  }
 59
 60  &.logo-sm {
 61    width: 18px;
 62    height: 18px;
 63  }
 64}
 65
 66// ── Navbar ──
 67// `min-height` (not `height`) so the bar grows when the mobile collapse opens.
 68// A fixed `height: 52px` clipped the open menu — items rendered into the
 69// space below the bar but later siblings (breadcrumb-bar, main) painted on
 70// top of them, so they read as completely invisible on phones.
 71
 72.navbar {
 73  min-height: 52px;
 74  padding: 0;
 75  background: #090806 !important;
 76  border-bottom: 1px solid rgba(107, 158, 120, 0.06);
 77
 78  > .container {
 79    min-height: 52px;
 80  }
 81
 82  .navbar-brand {
 83    display: flex;
 84    align-items: center;
 85    gap: 0.6rem;
 86    color: $white;
 87    font-weight: 600;
 88    letter-spacing: 0.1em;
 89    text-transform: uppercase;
 90    font-size: 0.78rem;
 91    text-decoration: none;
 92
 93    .brand-text { color: $white; }
 94    .brand-dot {
 95      display: inline-block;
 96      width: 6px; height: 6px; border-radius: 50%;
 97      background: $green;
 98    }
 99  }
100
101  .navbar-toggler {
102    color: rgba(221, 215, 205, 0.7);
103    padding: 0.35rem 0.55rem;
104    font-size: 1rem;
105
106    &:focus { box-shadow: none; }
107  }
108
109  .nav-link {
110    font-size: 0.8rem;
111    font-weight: 500;
112    letter-spacing: 0.05em;
113    text-transform: lowercase;
114    padding-left: 1rem !important;
115    padding-right: 1rem !important;
116    color: rgba(221, 215, 205, 0.6);
117    position: relative;
118    transition: color 200ms ease;
119
120    &::after {
121      content: '';
122      position: absolute;
123      bottom: 2px;
124      left: 1rem;
125      right: 1rem;
126      height: 1px;
127      background: $green;
128      transform: scaleX(0);
129      transition: transform 250ms ease;
130    }
131
132    &:hover,
133    &.active { color: $white; }
134
135    &:hover::after,
136    &.active::after { transform: scaleX(1); }
137  }
138
139  // ── Mobile (under 768px): stacked drawer ──
140  // Bootstrap's collapse drops the menu to a second flex row inside the
141  // navbar at this breakpoint. Style it as a tray under the brand row:
142  // top-rule separator, full-width tap targets, left-accent for the active
143  // item (instead of the desktop underline, which reads weird on stacked
144  // left-aligned items).
145  @media (max-width: 767.98px) {
146    .navbar-collapse {
147      width: 100%;
148      border-top: 1px solid rgba(107, 158, 120, 0.08);
149      margin-top: 0.25rem;
150      padding: 0.4rem 0 0.6rem;
151    }
152
153    .navbar-nav {
154      margin-left: 0 !important;
155      width: 100%;
156    }
157
158    .nav-link {
159      padding: 0.65rem 0.75rem !important;
160      border-left: 2px solid transparent;
161      border-radius: 2px;
162      transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
163
164      &::after { display: none; }
165
166      &:hover {
167        background: rgba(221, 215, 205, 0.04);
168        color: $white;
169      }
170
171      &.active {
172        color: $white;
173        border-left-color: $green;
174        background: rgba(107, 158, 120, 0.08);
175      }
176    }
177
178    .navbar-nav.ms-auto {
179      margin-top: 0.5rem;
180      padding-top: 0.6rem;
181      border-top: 1px solid rgba(107, 158, 120, 0.06);
182
183      .nav-item { width: 100%; }
184
185      .btn,
186      form,
187      .d-inline { width: 100%; }
188
189      .btn { width: 100%; }
190    }
191  }
192}
193
194// ── Breadcrumb bar ──
195
196.breadcrumb-bar {
197  background: rgba(107, 158, 120, 0.02);
198  border-bottom: 1px solid rgba(107, 158, 120, 0.04);
199
200  .breadcrumb { font-family: $font-family-monospace; }
201}
202
203// ── Section labels — amber caps, no prompt glyph ──
204
205.section-label {
206  font-size: 0.7rem;
207  font-weight: 600;
208  letter-spacing: 0.12em;
209  text-transform: uppercase;
210  color: rgba(201, 168, 76, 0.75);
211  font-family: $font-family-monospace;
212}
213
214// ── Cards (base) ──
215
216.card {
217  background: $card-bg;
218  border: 1px solid $card-border-color;
219  transition: border-color 250ms ease;
220
221  &:hover { border-color: rgba(107, 158, 120, 0.2); }
222}
223
224// ── Status dot ──
225
226.status-dot {
227  display: inline-block;
228  width: 8px; height: 8px;
229  border-radius: 50%;
230  margin-right: 0.55rem;
231  vertical-align: middle;
232  flex-shrink: 0;
233
234  &.status-dot-lg {
235    width: 14px; height: 14px;
236    margin-right: 0;
237  }
238
239  &.is-up { background: $green; box-shadow: 0 0 0 3px rgba(107, 158, 120, 0.12); }
240  &.is-down { background: $terracotta; box-shadow: 0 0 0 3px rgba(196, 112, 85, 0.12); }
241  &.is-warn { background: $amber; box-shadow: 0 0 0 3px rgba(201, 168, 76, 0.12); }
242  &.is-idle { background: #4a443c; }
243}
244
245// ── Visibility toggle (segmented pill) ──
246// Replaces the Bootstrap form-switch which was near-invisible on the dark
247// theme. Clear two-state UI — active half highlighted, inactive half dim.
248
249.toggle-label {
250  font-family: $font-family-monospace;
251  font-size: 0.68rem;
252  font-weight: 600;
253  letter-spacing: 0.12em;
254  text-transform: uppercase;
255  color: #847c72;
256  cursor: help;
257}
258
259.toggle-pill {
260  display: inline-flex;
261  align-items: stretch;
262  border: 1px solid rgba(107, 158, 120, 0.22);
263  border-radius: 999px;
264  overflow: hidden;
265  cursor: pointer;
266  background: #0e0d0a;
267  margin: 0;
268  user-select: none;
269  line-height: 1;
270
271  input {
272    position: absolute;
273    opacity: 0;
274    pointer-events: none;
275    width: 0; height: 0;
276  }
277
278  .toggle-pill-seg {
279    padding: 0.45rem 0.9rem;
280    font-family: $font-family-monospace;
281    font-size: 0.7rem;
282    font-weight: 600;
283    letter-spacing: 0.08em;
284    text-transform: uppercase;
285    color: #665f56;
286    transition: background 180ms ease, color 180ms ease;
287  }
288
289  // Default (unchecked) = Private is active
290  input ~ .toggle-pill-private {
291    background: rgba(201, 168, 76, 0.12);
292    color: #ddc06a;
293  }
294
295  // Checked = Public is active
296  input:checked ~ .toggle-pill-private {
297    background: transparent;
298    color: #665f56;
299  }
300  input:checked ~ .toggle-pill-public {
301    background: $green-dim;
302    color: $green-bright;
303  }
304
305  &:hover {
306    border-color: rgba(107, 158, 120, 0.35);
307  }
308}
309
310// ── Metric tile ──
311// Every tile fills its grid cell so a row of them all share one height, even
312// when content length varies (e.g. one tile has a sub-line, others don't).
313
314.metric-tile {
315  background: $card-bg;
316  border: 1px solid $card-border-color;
317  border-radius: $border-radius;
318  padding: 1rem 1.15rem;
319  height: 100%;
320  display: flex;
321  flex-direction: column;
322
323  .metric-label {
324    font-size: 0.68rem;
325    font-weight: 600;
326    letter-spacing: 0.12em;
327    text-transform: uppercase;
328    color: #847c72;
329  }
330
331  .metric-value {
332    font-size: 1.75rem;
333    font-weight: 700;
334    line-height: 1.1;
335    color: $white;
336    margin-top: 0.35rem;
337    letter-spacing: -0.01em;
338  }
339
340  .metric-sub {
341    font-size: 0.72rem;
342    color: #847c72;
343    margin-top: auto;  // Pins sub to the bottom so all tiles baseline-align
344    padding-top: 0.35rem;
345    letter-spacing: 0.02em;
346  }
347
348  &.metric-accent-green {
349    border-color: $green-border;
350    .metric-value { color: $green-bright; }
351  }
352  &.metric-accent-amber {
353    border-color: $amber-border;
354    .metric-value { color: #ddc06a; }
355  }
356  &.metric-accent-danger {
357    border-color: $terracotta-border;
358    .metric-value { color: #d88870; }
359  }
360}
361
362// ── Chips (inline status/score) ──
363
364.chip {
365  display: inline-flex;
366  align-items: center;
367  gap: 0.4rem;
368  font-family: $font-family-monospace;
369  font-size: 0.7rem;
370  font-weight: 600;
371  letter-spacing: 0.05em;
372  text-transform: uppercase;
373  padding: 0.3rem 0.6rem;
374  border-radius: 2px;
375  border: 1px solid transparent;
376  line-height: 1;
377
378  &.chip-ok {
379    background: $green-dim;
380    color: $green-bright;
381    border-color: $green-border;
382  }
383  &.chip-down {
384    background: $terracotta-dim;
385    color: #e38871;
386    border-color: $terracotta-border;
387  }
388  &.chip-warn {
389    background: $amber-dim;
390    color: #ddc06a;
391    border-color: $amber-border;
392  }
393  &.chip-info {
394    background: rgba(126, 170, 184, 0.08);
395    color: #9ec5d2;
396    border-color: rgba(126, 170, 184, 0.22);
397  }
398  &.chip-muted {
399    background: rgba(221, 215, 205, 0.04);
400    color: #847c72;
401    border-color: rgba(221, 215, 205, 0.08);
402  }
403}
404
405// ── Footer ──
406
407footer {
408  padding-top: 4rem;
409  padding-bottom: 3rem;
410  position: relative;
411  background: #090806;
412  border-top: 1px solid rgba(107, 158, 120, 0.06);
413
414  .h5 {
415    font-size: 0.7rem;
416    letter-spacing: 0.12em;
417    text-transform: uppercase;
418    color: rgba(201, 168, 76, 0.55);
419    font-weight: 600;
420  }
421
422  p {
423    color: rgba(221, 215, 205, 0.5);
424    font-size: 0.85rem;
425    line-height: 1.75;
426
427    a {
428      color: rgba(221, 215, 205, 0.75);
429      text-decoration: underline;
430      text-underline-offset: 2px;
431
432      &:hover { color: $white; }
433    }
434  }
435
436  .links {
437    padding-top: 2rem;
438    padding-bottom: 1rem;
439  }
440}
441
442.footer-bar {
443  background: #050403;
444  border-top: 1px solid rgba(107, 158, 120, 0.04);
445  padding: 0.8rem 0;
446  color: rgba(221, 215, 205, 0.3);
447  font-size: 0.78rem;
448
449  small { color: rgba(221, 215, 205, 0.3); }
450
451  &-link {
452    color: rgba(221, 215, 205, 0.3);
453    transition: color 200ms ease;
454
455    &:hover { color: $white; }
456  }
457}
458
459// ── Uptime strip ──
460
461.uptime-strip {
462  display: flex;
463  gap: 2px;
464  align-items: flex-end;
465  height: 20px;
466
467  .uptime-tick {
468    flex: 1 1 auto;
469    min-width: 2px;
470    height: 100%;
471    background: #211e1a;
472    border-radius: 1px;
473
474    &.is-up { background: $green; opacity: 0.7; }
475    &.is-down { background: $terracotta; opacity: 0.85; }
476    &.is-warn { background: $amber; opacity: 0.7; }
477    &.is-none { background: #18160f; }
478  }
479}
480
481// ── Terminal-style block ──
482
483.terminal-block {
484  background: rgba(9, 8, 6, 0.7);
485  border: 1px solid rgba(107, 158, 120, 0.15);
486  border-radius: $border-radius;
487  font-family: $font-family-monospace;
488  font-size: 0.8rem;
489  color: $green-bright;
490  padding: 1rem 1.2rem;
491  line-height: 1.8;
492
493  .t-line { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
494  .t-prompt { color: $amber; margin-right: 0.4rem; }
495  .t-out { color: $gray-200; }
496  .t-comment { color: #665f56; }
497  .t-key { color: $amber; }
498  .t-val { color: $green-bright; }
499  .t-cursor {
500    display: inline-block; width: 7px; height: 0.9em; vertical-align: -2px;
501    background: $green-bright;
502    animation: t-blink 1s steps(1) infinite;
503  }
504}
505
506@keyframes t-blink {
507  0%, 50% { opacity: 1; }
508  51%, 100% { opacity: 0; }
509}
510
511// ── Property row ──
512
513.property-row {
514  display: grid;
515  grid-template-columns: minmax(0, 1fr) auto;
516  gap: 1rem 1.5rem;
517  background: $card-bg;
518  border: 1px solid $card-border-color;
519  border-radius: $border-radius;
520  padding: 1rem 1.15rem;
521  margin-bottom: 0.75rem;
522  transition: border-color 200ms ease;
523
524  &:hover { border-color: rgba(107, 158, 120, 0.22); }
525
526  &.is-down { border-color: rgba(196, 112, 85, 0.3); }
527
528  .pr-main {
529    min-width: 0;
530    display: flex;
531    flex-direction: column;
532    gap: 0.35rem;
533  }
534
535  .pr-title {
536    font-weight: 600;
537    color: $white;
538    display: flex;
539    align-items: center;
540    min-width: 0;
541
542    a {
543      color: inherit;
544      text-decoration: none;
545      min-width: 0;
546      overflow: hidden;
547      text-overflow: ellipsis;
548      white-space: nowrap;
549
550      &:hover { color: $green-bright; }
551    }
552  }
553
554  .pr-url {
555    font-size: 0.73rem;
556    color: #847c72;
557    overflow: hidden;
558    text-overflow: ellipsis;
559    white-space: nowrap;
560  }
561
562  .pr-side {
563    display: flex;
564    flex-direction: column;
565    justify-content: space-between;
566    align-items: flex-end;
567    gap: 0.75rem;
568    min-height: 68px; // Matches the left column's natural height so actions pin to bottom
569  }
570
571  // Uniform stat grid — each cell is label-over-chip so every column aligns
572  // vertically regardless of whether the value is a pill or a number.
573  .pr-meta {
574    display: flex;
575    gap: 0.85rem;
576    align-items: flex-end;
577    font-family: $font-family-monospace;
578
579    .pr-meta-cell {
580      display: flex;
581      flex-direction: column;
582      align-items: flex-start;
583      gap: 0.2rem;
584      min-width: 0;
585    }
586
587    .pr-meta-k {
588      color: #665f56;
589      text-transform: uppercase;
590      font-size: 0.6rem;
591      letter-spacing: 0.1em;
592      line-height: 1;
593    }
594  }
595
596  .pr-actions {
597    display: flex;
598    gap: 0.4rem;
599  }
600}
601
602@media (max-width: 767px) {
603  .property-row {
604    grid-template-columns: 1fr;
605
606    .pr-side {
607      min-height: 0;
608      align-items: stretch;
609    }
610    .pr-meta {
611      flex-wrap: wrap;
612      justify-content: flex-start;
613    }
614    .pr-actions {
615      justify-content: flex-end;
616    }
617  }
618}
619
620// ── Search form ──
621
622.search-form {
623  position: relative;
624
625  .search-icon {
626    position: absolute;
627    left: 0.9rem;
628    top: 50%;
629    transform: translateY(-50%);
630    color: #665f56;
631    pointer-events: none;
632    z-index: 2;
633  }
634
635  .search-input {
636    padding-left: 2.5rem;
637    font-size: 0.85rem;
638    border: 1px solid rgba(107, 158, 120, 0.15);
639    background: rgba(19, 18, 14, 0.7);
640    color: $body-color;
641    transition: border-color 200ms ease;
642
643    &::placeholder {
644      color: #665f56;
645      font-style: normal;
646    }
647
648    &:focus {
649      border-color: rgba(107, 158, 120, 0.4);
650      box-shadow: 0 0 0 2px rgba(107, 158, 120, 0.1);
651      background: #13120e;
652    }
653  }
654}
655
656// ── Dashboard toolbar ──
657// Input + button sharing one visual line — both get the same height (38px)
658// so the CTA doesn't read as a different size from the field next to it.
659
660.dashboard-toolbar {
661  display: flex;
662  gap: 0.5rem;
663  align-items: stretch;
664
665  .form-control {
666    height: 38px;
667    font-size: 0.85rem;
668  }
669
670  .btn {
671    height: 38px;
672    padding: 0 1.1rem;
673    display: inline-flex;
674    align-items: center;
675    white-space: nowrap;
676  }
677}
678
679// ── Chart panel ──
680
681.chart-panel {
682  background: $card-bg;
683  border: 1px solid $card-border-color;
684  border-radius: $border-radius;
685  padding: 1rem 1.15rem;
686
687  .chart-panel-header {
688    display: flex;
689    align-items: center;
690    justify-content: space-between;
691    margin-bottom: 0.75rem;
692  }
693
694  .chart-panel-title {
695    font-size: 0.68rem;
696    font-weight: 600;
697    letter-spacing: 0.12em;
698    text-transform: uppercase;
699    color: rgba(201, 168, 76, 0.75);
700    font-family: $font-family-monospace;
701  }
702}
703
704// ── Security list ──
705
706.check-list {
707  background: $card-bg;
708  border: 1px solid $card-border-color;
709  border-radius: $border-radius;
710  overflow: hidden;
711
712  .check-list-header {
713    background: rgba(107, 158, 120, 0.04);
714    padding: 0.6rem 1rem;
715    font-size: 0.68rem;
716    font-weight: 600;
717    letter-spacing: 0.12em;
718    text-transform: uppercase;
719    color: rgba(201, 168, 76, 0.75);
720    font-family: $font-family-monospace;
721    border-bottom: 1px solid rgba(107, 158, 120, 0.1);
722  }
723
724  .check-list-item {
725    display: flex;
726    justify-content: space-between;
727    align-items: center;
728    padding: 0.55rem 1rem;
729    font-size: 0.85rem;
730    border-bottom: 1px solid rgba(107, 158, 120, 0.04);
731
732    &:last-child { border-bottom: none; }
733
734    .check-name {
735      color: $gray-300;
736      display: flex;
737      align-items: center;
738      gap: 0.5rem;
739    }
740  }
741}
742
743// ── Monitor card ──
744// When used inside a flex/grid row, `h-100` class stretches the card to its
745// cell height. The body grows to fill any extra space so the two cards next
746// to each other stay visually balanced even with different dl row counts.
747
748.monitor-card {
749  background: $card-bg;
750  border: 1px solid $card-border-color;
751  border-radius: $border-radius;
752  overflow: hidden;
753  display: flex;
754  flex-direction: column;
755
756  .monitor-header {
757    display: flex;
758    justify-content: space-between;
759    align-items: center;
760    padding: 0.7rem 1rem;
761    background: rgba(107, 158, 120, 0.04);
762    border-bottom: 1px solid rgba(107, 158, 120, 0.08);
763    flex-shrink: 0;
764
765    .monitor-title {
766      font-family: $font-family-monospace;
767      font-size: 0.78rem;
768      font-weight: 600;
769      letter-spacing: 0.06em;
770      text-transform: uppercase;
771      color: $white;
772    }
773  }
774
775  .monitor-body {
776    padding: 0.9rem 1rem;
777    flex: 1 1 auto;
778
779    dl {
780      margin: 0;
781      display: grid;
782      grid-template-columns: max-content 1fr;
783      gap: 0.4rem 1rem;
784    }
785
786    dt {
787      font-size: 0.7rem;
788      letter-spacing: 0.06em;
789      text-transform: uppercase;
790      color: #665f56;
791      font-weight: 500;
792    }
793
794    dd {
795      margin: 0;
796      font-size: 0.8rem;
797      color: $gray-200;
798      font-family: $font-family-monospace;
799    }
800  }
801}
802
803// ── Monitor card buttons ──
804// Inline flex so the spinner sits centered next to the label instead of
805// floating off the baseline. Slightly thicker spinner border for visibility
806// against the muted button outline.
807
808.monitor-btn {
809  display: inline-flex;
810  align-items: center;
811  gap: 0.4rem;
812  padding: 0.2rem 0.65rem;
813  line-height: 1.3;
814
815  .spinner-border-sm {
816    --bs-spinner-width: 0.85rem;
817    --bs-spinner-height: 0.85rem;
818    --bs-spinner-border-width: 0.2em;
819    color: $green-bright;
820    flex-shrink: 0;
821  }
822
823  &:disabled {
824    opacity: 0.85;  // Bootstrap's default 0.65 makes the spinner nearly invisible
825  }
826}
827
828// ── Insight row (lighthouse opportunities / crawler issues) ──
829
830.insight-header {
831  display: grid;
832  grid-template-columns: 110px 1fr 1fr 140px;
833  gap: 1rem;
834  padding: 0.55rem 1rem;
835  background: rgba(107, 158, 120, 0.04);
836  border: 1px solid rgba(107, 158, 120, 0.08);
837  border-radius: $border-radius;
838  font-family: $font-family-monospace;
839  font-size: 0.68rem;
840  letter-spacing: 0.08em;
841  text-transform: uppercase;
842  color: rgba(201, 168, 76, 0.75);
843  margin-bottom: 0.6rem;
844}
845
846.insight-row {
847  display: grid;
848  grid-template-columns: 110px 1fr 1fr 140px;
849  gap: 1rem;
850  padding: 0.65rem 1rem;
851  background: $card-bg;
852  border: 1px solid $card-border-color;
853  border-radius: $border-radius;
854  margin-bottom: 0.4rem;
855  font-size: 0.85rem;
856  align-items: center;
857
858  &:hover { border-color: rgba(107, 158, 120, 0.2); }
859
860  .insight-col-trunc {
861    min-width: 0;
862    overflow: hidden;
863    text-overflow: ellipsis;
864    white-space: nowrap;
865  }
866}
867
868.insight-header.insight--3col,
869.insight-row.insight--3col {
870  grid-template-columns: 1fr 1fr 140px;
871}
872
873@media (max-width: 767px) {
874  .insight-header { display: none; }
875  .insight-row {
876    grid-template-columns: 1fr;
877    gap: 0.4rem;
878  }
879}
880
881// ── Auth split view ──
882
883.auth-shell {
884  min-height: calc(100vh - 52px);
885  display: grid;
886  grid-template-columns: 1fr 1fr;
887
888  @media (max-width: 991px) {
889    grid-template-columns: 1fr;
890  }
891
892  .auth-form-col {
893    padding: 3rem 2rem;
894    display: flex;
895    align-items: center;
896    justify-content: center;
897  }
898
899  .auth-visual-col {
900    position: relative;
901    overflow: hidden;
902    background: linear-gradient(145deg, #090806 0%, #0e0d0a 60%, #13120e 100%);
903    border-left: 1px solid rgba(107, 158, 120, 0.08);
904
905    @media (max-width: 991px) { display: none; }
906  }
907
908  .auth-form-wrap {
909    width: 100%;
910    max-width: 380px;
911  }
912}