/* ==========================================================================
   BeastFarmerAI — design system
   Palet: "Blue Titanium" (deep desaturated blue) + aksen hijau neon dari logo.
   ========================================================================== */

:root {
  /* --- dasar --- */
  --bg:          #060910;
  --bg-elev:     #0B1220;
  --bg-2:        #0F1826;

  /* --- permukaan kaca --- */
  --panel:       rgba(150, 185, 230, 0.045);
  --panel-hover: rgba(150, 185, 230, 0.08);
  --border:      rgba(150, 185, 230, 0.11);
  --border-str:  rgba(150, 185, 230, 0.22);

  /* --- teks --- */
  --text:        #E8EFFA;
  --text-dim:    #94A6BF;
  --text-faint:  #5E7089;

  /* --- aksen utama: hijau neon (dari logo) --- */
  --brand:       #A3E635;
  --brand-soft:  #C6F45C;
  --brand-deep:  #7CC217;
  --brand-glow:  rgba(163, 230, 53, 0.34);

  /* --- aksen sekunder: titanium blue --- */
  --violet:      #5B8DEF;
  --violet-glow: rgba(91, 141, 239, 0.30);
  --titanium:    #3E5064;
  --titanium-lt: #6E8BAA;

  --green:       #34D399;
  --amber:       #FBBF24;
  --red:         #FB7185;

  --radius:      18px;
  --radius-sm:   11px;
  --shadow:      0 30px 70px -24px rgba(0, 0, 0, 0.9);

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --mono: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  min-height: 100vh;
}

a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--brand-glow); color: #fff; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(150, 185, 230, 0.14); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: rgba(150, 185, 230, 0.26); }

/* ==========================================================================
   LATAR BERANIMASI — "Flow Field"
   Partikel canvas mengikuti medan vektor noise dan meninggalkan jejak tipis.
   Lapisannya: canvas (paling bawah) → glow biru → kisi + butiran film.
   Gradien pada .fx jadi cadangan kalau JS/canvas tidak jalan.
   ========================================================================== */

.fx {
  position: fixed;
  inset: 0;
  z-index: -3;
  overflow: hidden;
  pointer-events: none;
  background: radial-gradient(140% 110% at 50% -20%, #16243E 0%, #0B1526 42%, var(--bg) 78%);
}

/* Canvas tidak boleh menangkap pointer — link & tombol di atasnya harus tetap bisa diklik. */
.fx-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

/* Ambience biru titanium di atas partikel, plus sedikit hijau di bawah. */
.fx-glow {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 50% -15%, rgba(38, 84, 158, 0.4), transparent 62%),
    radial-gradient(70% 55% at 88% 104%, rgba(163, 230, 53, 0.08), transparent 64%);
}

/* Kisi halus + butiran film supaya latar tidak terasa "plastik" */
.fx-grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(150, 185, 230, 0.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(150, 185, 230, 0.028) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 25%, transparent 80%);
}
.fx-grid::after {
  content: '';
  position: absolute; inset: 0;
  opacity: 0.3;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

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

/* ------------------------------- layout ---------------------------------- */

.wrap { width: min(1200px, 100% - 40px); margin-inline: auto; }
.wrap-sm { width: min(880px, 100% - 40px); margin-inline: auto; }

.row { display: flex; align-items: center; gap: 12px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.col { display: flex; flex-direction: column; gap: 12px; }
.grow { flex: 1; }
.center { text-align: center; }
.hide { display: none !important; }

/* ------------------------------- topbar ---------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: blur(22px) saturate(170%);
  background: rgba(8, 13, 22, 0.7);
  border-bottom: 1px solid var(--border);
}
.topbar .inner { display: flex; align-items: center; justify-content: space-between; height: 70px; gap: 20px; }

.brand { display: flex; align-items: center; gap: 12px; font-weight: 750; letter-spacing: -0.025em; font-size: 1.08rem; }
.brand-mark {
  width: 38px; height: 38px;
  border-radius: 11px;
  overflow: hidden;
  flex-shrink: 0;
  border: 1px solid rgba(163, 230, 53, 0.32);
  box-shadow: 0 6px 22px -8px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, 0.1);
  background: #05070B;
}
.brand-mark img { width: 100%; height: 100%; object-fit: cover; }
.brand span { color: var(--brand); font-weight: 750; }

.nav { display: flex; align-items: center; gap: 4px; }
/* :not(.btn) penting — tanpa itu aturan ini menang spesifisitas atas
   .btn-primary dan teks tombol "Daftar" jadi abu-abu di atas hijau neon. */
.nav a:not(.btn) {
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 0.9rem;
  color: var(--text-dim);
  font-weight: 500;
  transition: color 0.18s, background 0.18s;
}
.nav a:not(.btn):hover { color: var(--text); background: var(--panel); }
.nav a.active { color: var(--brand); background: rgba(163, 230, 53, 0.1); }

/* ------------------------------- buttons --------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 18px;
  border-radius: 12px;
  border: 1px solid var(--border-str);
  background: var(--panel);
  font-size: 0.9rem; font-weight: 600;
  cursor: pointer;
  transition: transform 0.16s, background 0.18s, border-color 0.18s, box-shadow 0.18s, opacity 0.18s;
  white-space: nowrap;
  position: relative;
}
.btn:hover { background: var(--panel-hover); border-color: var(--border-str); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* Hijau neon dengan teks gelap — kontras tertinggi di latar biru tua. */
.btn-primary {
  background: linear-gradient(135deg, var(--brand-soft), var(--brand) 55%, var(--brand-deep));
  border-color: transparent;
  color: #08130A;
  font-weight: 700;
  box-shadow: 0 12px 34px -14px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, 0.32);
}
.btn-primary:hover {
  background: linear-gradient(135deg, #D6FA72, var(--brand-soft) 55%, var(--brand));
  box-shadow: 0 16px 42px -14px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, 0.4);
}

.btn-violet { background: linear-gradient(135deg, var(--violet), #3A63C4); border-color: transparent; color: #fff; }
.btn-ghost { background: rgba(150, 185, 230, 0.03); border-color: var(--border); }
.btn-ghost:hover { border-color: rgba(163, 230, 53, 0.3); color: var(--brand-soft); }
.btn-danger { background: rgba(251, 113, 133, 0.12); border-color: rgba(251, 113, 133, 0.32); color: #FDA4AF; }
.btn-danger:hover { background: rgba(251, 113, 133, 0.2); border-color: rgba(251, 113, 133, 0.5); color: #FDA4AF; }
.btn-sm { padding: 6px 12px; font-size: 0.8rem; border-radius: 9px; }
.btn-lg { padding: 15px 30px; font-size: 1rem; border-radius: 14px; }
.btn-block { width: 100%; }

/* ------------------------------- surfaces -------------------------------- */

.card {
  background: linear-gradient(180deg, rgba(150, 185, 230, 0.06), rgba(150, 185, 230, 0.02));
  backdrop-filter: blur(14px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  position: relative;
  overflow: hidden;
}
/* Garis kilau tipis di tepi atas — kesan permukaan logam. */
.card::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(163, 230, 53, 0.35), rgba(91, 141, 239, 0.3), transparent);
}
.card-pad-lg { padding: 32px; }

.panel {
  background: rgba(11, 18, 32, 0.72);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.panel-head {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.panel-head h3 { font-size: 0.98rem; font-weight: 650; letter-spacing: -0.01em; }
.panel-body { padding: 20px; }

/* ------------------------------- typography ------------------------------ */

h1, h2, h3, h4 { letter-spacing: -0.03em; line-height: 1.12; font-weight: 750; }
h1 { font-size: clamp(2.4rem, 6.2vw, 4.3rem); }
h2 { font-size: clamp(1.75rem, 3.6vw, 2.7rem); }
h3 { font-size: 1.15rem; }

.muted { color: var(--text-dim); }
.faint { color: var(--text-faint); }
.small { font-size: 0.85rem; }
.tiny { font-size: 0.76rem; }
.mono { font-family: var(--mono); }

.gradient-text {
  background: linear-gradient(105deg, #FFFFFF 4%, var(--brand-soft) 42%, var(--brand) 62%, var(--violet) 96%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 7px 15px 7px 9px;
  border-radius: 999px;
  border: 1px solid var(--border-str);
  background: rgba(150, 185, 230, 0.05);
  backdrop-filter: blur(10px);
  font-size: 0.79rem; font-weight: 550; color: var(--text-dim);
}
.eyebrow b { color: var(--brand); font-weight: 700; }

.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 3px rgba(163, 230, 53, 0.16); }
.dot-pulse { animation: pulse 2.2s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ------------------------------- badges ---------------------------------- */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.73rem; font-weight: 650;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
}
.badge-green  { background: rgba(52, 211, 153, 0.13); color: #6EE7B7; border-color: rgba(52, 211, 153, 0.26); }
.badge-amber  { background: rgba(251, 191, 36, 0.13); color: var(--amber); border-color: rgba(251, 191, 36, 0.26); }
.badge-red    { background: rgba(251, 113, 133, 0.13); color: #FDA4AF; border-color: rgba(251, 113, 133, 0.26); }
.badge-violet { background: rgba(91, 141, 239, 0.16); color: #93B4F7; border-color: rgba(91, 141, 239, 0.32); }
.badge-gray   { background: rgba(150, 185, 230, 0.07); color: var(--text-dim); border-color: var(--border); }
.badge-brand  { background: rgba(163, 230, 53, 0.15); color: var(--brand); border-color: rgba(163, 230, 53, 0.34); }

/* ------------------------------- forms ----------------------------------- */

.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: 0.83rem; font-weight: 600; color: var(--text-dim); }

.input, select.input, textarea.input {
  width: 100%;
  padding: 12px 15px;
  background: rgba(4, 8, 15, 0.55);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  transition: border-color 0.18s, box-shadow 0.18s, background 0.18s;
  outline: none;
}
.input::placeholder { color: var(--text-faint); }
.input:focus {
  border-color: rgba(163, 230, 53, 0.55);
  box-shadow: 0 0 0 3px rgba(163, 230, 53, 0.13);
  background: rgba(4, 8, 15, 0.72);
}
select.input { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%2394A6BF' d='M6 8.5 2 4.5h8z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 12px; padding-right: 34px; }
textarea.input { resize: vertical; min-height: 88px; font-family: var(--mono); font-size: 0.84rem; }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }

/* ------------------------------- tables ---------------------------------- */

.table-scroll { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 0.86rem; min-width: 640px; }
table.data th {
  text-align: left;
  padding: 12px 16px;
  font-size: 0.72rem; font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  background: rgba(150, 185, 230, 0.02);
}
table.data td { padding: 13px 16px; border-bottom: 1px solid rgba(150, 185, 230, 0.055); vertical-align: middle; }
table.data tr:last-child td { border-bottom: none; }
table.data tbody tr { transition: background 0.15s; }
table.data tbody tr:hover { background: rgba(150, 185, 230, 0.035); }
.cell-actions { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }

/* ------------------------------- stats ----------------------------------- */

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }
.stat {
  background: linear-gradient(180deg, rgba(150, 185, 230, 0.065), rgba(150, 185, 230, 0.02));
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 20px;
  position: relative;
  overflow: hidden;
  transition: border-color 0.2s, transform 0.2s;
}
.stat:hover { border-color: rgba(163, 230, 53, 0.24); transform: translateY(-2px); }
.stat::after {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--brand-glow), transparent);
}
.stat .label { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint); font-weight: 650; }
.stat .value { font-size: 1.8rem; font-weight: 750; letter-spacing: -0.035em; margin-top: 6px; line-height: 1.1; }
.stat .sub { font-size: 0.78rem; color: var(--text-dim); margin-top: 3px; }

/* ------------------------------- progress -------------------------------- */

.progress { height: 7px; border-radius: 99px; background: rgba(150, 185, 230, 0.1); overflow: hidden; }
.progress > i {
  display: block; height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--brand-deep), var(--brand-soft));
  box-shadow: 0 0 12px -2px var(--brand-glow);
  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.progress.warn > i { background: linear-gradient(90deg, #D97706, var(--amber)); box-shadow: none; }
.progress.danger > i { background: linear-gradient(90deg, #E11D48, var(--red)); box-shadow: none; }

/* --------------------------- key display --------------------------------- */

.keybox {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 15px;
  background: rgba(4, 8, 15, 0.62);
  border: 1px solid rgba(163, 230, 53, 0.22);
  border-radius: var(--radius-sm);
  font-family: var(--mono); font-size: 0.82rem;
  overflow: hidden;
}
.keybox code { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--brand); }

/* ------------------------------- code block ------------------------------ */

.code {
  background: rgba(4, 8, 15, 0.66);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
}
.code-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 15px;
  border-bottom: 1px solid var(--border);
  background: rgba(150, 185, 230, 0.03);
  font-size: 0.78rem; color: var(--text-dim);
}
.code pre { padding: 17px; overflow-x: auto; font-family: var(--mono); font-size: 0.8rem; line-height: 1.75; }
.code .t-key { color: #7DD3FC; }
.code .t-str { color: var(--brand); }
.code .t-com { color: var(--text-faint); font-style: italic; }
.code .t-fn  { color: #93B4F7; }

.tabs {
  display: flex; gap: 4px; padding: 4px;
  background: rgba(4, 8, 15, 0.45); border: 1px solid var(--border);
  border-radius: 13px; width: fit-content; max-width: 100%; overflow-x: auto;
}
.tabs button {
  padding: 8px 17px; border: none; background: transparent; border-radius: 10px;
  font-size: 0.85rem; font-weight: 600; color: var(--text-dim); cursor: pointer;
  transition: background 0.18s, color 0.18s; white-space: nowrap;
}
.tabs button:hover { color: var(--text); }
.tabs button.active { background: rgba(150, 185, 230, 0.1); color: var(--brand); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); }

/* ------------------------------- modal ----------------------------------- */

.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(2, 5, 10, 0.74);
  backdrop-filter: blur(8px);
  display: grid; place-items: center;
  padding: 20px;
  animation: fade 0.18s ease;
}
.modal {
  width: min(560px, 100%);
  max-height: 88vh; overflow-y: auto;
  background: rgba(11, 18, 32, 0.96);
  border: 1px solid var(--border-str);
  border-radius: 20px;
  box-shadow: var(--shadow);
  animation: pop 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.3);
}
.modal-head { padding: 20px 24px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.modal-body { padding: 24px; display: flex; flex-direction: column; gap: 16px; }
.modal-foot { padding: 16px 24px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.x-btn { background: none; border: none; color: var(--text-faint); font-size: 1.4rem; cursor: pointer; line-height: 1; padding: 4px 8px; border-radius: 8px; }
.x-btn:hover { color: var(--text); background: var(--panel); }

@keyframes fade { from { opacity: 0; } }
@keyframes pop { from { opacity: 0; transform: scale(0.96) translateY(10px); } }

/* ------------------------------- toast ----------------------------------- */

#toasts { position: fixed; bottom: 24px; right: 24px; z-index: 200; display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }
.toast {
  padding: 13px 19px;
  border-radius: 13px;
  background: rgba(11, 18, 32, 0.97);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border-str);
  box-shadow: var(--shadow);
  font-size: 0.87rem; font-weight: 500;
  max-width: 360px;
  animation: slide 0.25s cubic-bezier(0.2, 0.9, 0.3, 1.2);
  border-left: 3px solid var(--brand);
}
.toast.ok { border-left-color: var(--green); }
.toast.err { border-left-color: var(--red); }
@keyframes slide { from { opacity: 0; transform: translateX(24px); } }

/* ------------------------------- misc ------------------------------------ */

.empty { padding: 46px 20px; text-align: center; color: var(--text-faint); font-size: 0.9rem; }
.divider { height: 1px; background: var(--border); border: none; margin: 4px 0; }
.spinner {
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid rgba(150, 185, 230, 0.25); border-top-color: var(--brand);
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.sparkline { display: flex; align-items: flex-end; gap: 3px; height: 54px; }
.sparkline i {
  flex: 1; min-width: 4px;
  background: linear-gradient(180deg, var(--brand), rgba(163, 230, 53, 0.14));
  border-radius: 3px 3px 0 0;
  min-height: 3px;
  transition: opacity 0.18s;
}
.sparkline i:hover { opacity: 0.7; }

.alert {
  padding: 14px 17px;
  border-radius: var(--radius-sm);
  font-size: 0.86rem;
  border: 1px solid;
  display: flex; gap: 10px; align-items: flex-start;
}
.alert-err   { background: rgba(251, 113, 133, 0.09); border-color: rgba(251, 113, 133, 0.28); color: #FDA4AF; }
.alert-ok    { background: rgba(52, 211, 153, 0.09);  border-color: rgba(52, 211, 153, 0.28);  color: #6EE7B7; }
.alert-info  { background: rgba(91, 141, 239, 0.09);  border-color: rgba(91, 141, 239, 0.28);  color: #A5C0F9; }
.alert-warn  { background: rgba(251, 191, 36, 0.09);  border-color: rgba(251, 191, 36, 0.28);  color: #FCD34D; }

/* --------------------------- auth pages ---------------------------------- */

.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: 40px 20px; }
.auth-card { width: min(430px, 100%); }
.auth-card .card { padding: 34px; }

/* --------------------------- responsive ---------------------------------- */

@media (max-width: 760px) {
  .nav a { padding: 7px 10px; font-size: 0.85rem; }
  .brand span { display: none; }
  .card-pad-lg { padding: 24px; }
  #toasts { left: 16px; right: 16px; bottom: 16px; align-items: stretch; }
  .toast { max-width: none; }
}

/* ==========================================================================
   EFEK KETIK ALA TERMINAL
   Semua karakter sudah ada di DOM sejak awal (opacity 0), lalu dimunculkan
   satu per satu. Dengan begitu tinggi baris terkunci sejak render pertama
   dan teks di bawahnya tidak melompat-lompat saat mengetik.
   ========================================================================== */

.type-line { display: inline; }
.type-line .ch {
  opacity: 0;
  font-style: normal;
  transition: opacity 0.06s linear;
}
.type-line .ch.on { opacity: 1; }

/* Baris bergradasi perlu perlakuan khusus: kalau background-clip:text dipasang
   di elemen baris, gradasinya dicat oleh induk dan dipotong ke SELURUH glif —
   termasuk karakter yang masih opacity 0, sehingga baris langsung terlihat utuh.
   Solusinya gradasi dipindah ke tiap karakter, dengan background-size selebar
   baris dan posisi digeser sesuai letak karakter, supaya tetap menyambung. */
.type-line.gradient-text { background: none; }
.type-line.gradient-text .ch {
  background-image: linear-gradient(105deg, #FFFFFF 4%, var(--brand-soft) 42%, var(--brand) 62%, var(--violet) 96%);
  background-size: var(--lw, 100%) 100%;
  background-position: calc(-1 * var(--x, 0px)) center;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
}

/* Kursor blok berkedip. Lebarnya 0 supaya bisa disisipkan tepat setelah
   karakter terakhir tanpa menggeser sisa teks (yang masih tersembunyi). */
.caret {
  display: inline-block;
  width: 0;
  height: 0.92em;
  vertical-align: -0.1em;
  position: relative;
}
.caret::before {
  content: '';
  position: absolute;
  left: 0.06em; top: 0;
  width: 0.56em; height: 100%;
  background: var(--brand);
  box-shadow: 0 0 14px var(--brand-glow);
  animation: caret 1s steps(1) infinite;
}
@keyframes caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* Elemen yang menyusul setelah ketikan selesai */
.reveal { opacity: 0; transform: translateY(14px); }
.reveal.shown { opacity: 1; transform: none; transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.8, 0.3, 1); }

@media (prefers-reduced-motion: reduce) {
  .type-line .ch { opacity: 1 !important; }
  .type-line.typing::after { display: none; }
  .reveal { opacity: 1 !important; transform: none !important; }
}
