
/* v3 layout: same as v2, hero signature moment replaced — a particle swarm streams in from off-screen, fuses into the monogram, then hands off to the crisp SVG */
:root {
  --bg: #F5F8FB;
  --bg-soft: #EDF2F8;
  --fg: #1C1C24;
  --fg-2: #5C6575;
  --card: #FFFFFF;
  --card-2: #F9FBFD;
  --line: #DDE5EE;
  --line-2: #CBD6E3;
  --accent: #00F2FE;
  --blue: #0072FF;
  --grad: linear-gradient(100deg, #00F2FE 0%, #0072FF 100%);
  --grad-135: linear-gradient(135deg, #00F2FE 0%, #0072FF 100%);
  --glow: rgba(0, 114, 255, 0.14);
  --glow-2: rgba(0, 242, 254, 0.16);
  --halo: rgba(0, 114, 255, 0.30);
  --halo-strong: rgba(0, 114, 255, 0.42);
  --btn-fg: #061523;
  --danger: #C03B3B;
  --shadow: 0 0 0 1px var(--line), 0 0 28px -12px rgba(28, 28, 36, 0.35);
  --shadow-lift: 0 0 0 1px var(--line-2), 0 0 44px -10px rgba(0, 114, 255, 0.30);
  /* every stack names the site's Arabic fonts right after its Latin one: the Latin fonts
     have no Arabic letters, so without this the browser grabs a random system font for
     any Arabic text set in them (badges, tags, chips, kickers, the Customize menu) */
  --font-display: "Montserrat", "Manrope", "Tajawal", "IBM Plex Sans Arabic", system-ui, sans-serif;
  --font-body: "Manrope", "IBM Plex Sans Arabic", "Tajawal", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", "IBM Plex Sans Arabic", "Tajawal", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --t1: clamp(30px, 6.4vw, 58px);
  --t2: clamp(21px, 3.4vw, 32px);
  --t3: clamp(17px, 2vw, 20px);
  --nav-h: 64px;
  --r-card: 18px;
  --r-btn: 999px;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1C1C24;
    --bg-soft: #22222C;
    --fg: #F2F5FA;
    --fg-2: #9AA3B2;
    --card: #24242E;
    --card-2: #2A2A35;
    --line: #33333F;
    --line-2: #454553;
    --glow: rgba(0, 114, 255, 0.22);
    --glow-2: rgba(0, 242, 254, 0.10);
    --halo: rgba(0, 114, 255, 0.50);
    --halo-strong: rgba(0, 114, 255, 0.62);
    --btn-fg: #04121F;
    --danger: #FF8585;
    --shadow: 0 0 0 1px var(--line), 0 0 30px -10px rgba(0, 0, 0, 0.60);
    --shadow-lift: 0 0 0 1px var(--line-2), 0 0 48px -8px rgba(0, 114, 255, 0.45);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #1C1C24;
  --bg-soft: #22222C;
  --fg: #F2F5FA;
  --fg-2: #9AA3B2;
  --card: #24242E;
  --card-2: #2A2A35;
  --line: #33333F;
  --line-2: #454553;
  --glow: rgba(0, 114, 255, 0.22);
  --glow-2: rgba(0, 242, 254, 0.10);
  --halo: rgba(0, 114, 255, 0.50);
  --halo-strong: rgba(0, 114, 255, 0.62);
  --btn-fg: #04121F;
  --danger: #FF8585;
  --shadow: 0 0 0 1px var(--line), 0 0 30px -10px rgba(0, 0, 0, 0.60);
  --shadow-lift: 0 0 0 1px var(--line-2), 0 0 48px -8px rgba(0, 114, 255, 0.45);
  color-scheme: dark;
}
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.35s ease, color 0.35s ease;
}
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto;
  height: env(safe-area-inset-top, 0px);
  z-index: 10;
  background: var(--bg);
  transition: background-color 0.35s ease;
}
::selection { background: rgba(0, 242, 254, 0.35); }
h1, h2, h3 { text-wrap: balance; }
a { color: inherit; }
/* taps and focus look the same on every button, card and link: no square tap
   highlight from the phone browser (the pieces press in instead), and the
   keyboard focus ring follows each element's own rounded shape */
html { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
:focus:not(:focus-visible) { outline: none; }
.skip {
  position: absolute; left: 16px; top: -60px; z-index: 200;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 16px; font-weight: 700; text-decoration: none;
  transition: top 0.2s ease;
}
.skip:focus-visible { top: 12px; }

/* ---------- nav ---------- */
.nav {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  transition: background-color 0.35s ease, border-color 0.35s ease;
}
.nav-inner {
  max-width: 1200px; margin: 0 auto; height: var(--nav-h);
  display: flex; align-items: center; gap: 12px;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}
.brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; min-width: 0;
}
.brand-mark {
  width: 30px; height: 30px; flex: none;
  border-radius: 9px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 2px rgba(0, 0, 0, 0.12);
  display: grid; place-items: center;
  transition: background-color 0.35s ease, border-color 0.35s ease;
}
.brand-name {
  font-family: var(--font-display);
  font-size: 16px; letter-spacing: -0.01em;
}
.brand-name b { font-weight: 800; }
.brand-name span { font-weight: 600; color: var(--fg-2); }
.nav-links {
  display: flex; align-items: center; gap: 26px;
  margin-left: auto;
}
.nav-links a {
  font-weight: 600; font-size: 15px; text-decoration: none;
  color: var(--fg-2); position: relative; padding: 6px 0;
  transition: color 0.2s ease;
}
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  border-radius: 2px; background: var(--grad);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.25s var(--ease-out);
}
.nav-links a:hover { color: var(--fg); }
.nav-links a:hover::after { transform: scaleX(1); }
.nav-actions { display: flex; align-items: center; gap: 10px; }
@media (max-width: 719px) {
  .nav-links {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    margin-left: 0;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
    padding-block: 6px 12px;
    padding-inline: max(16px, env(safe-area-inset-left, 0px)) max(16px, env(safe-area-inset-right, 0px));
    transition: background-color 0.35s ease, border-color 0.35s ease;
  }
  .nav.open .nav-links { display: flex; }
  .nav-links a {
    padding-block: 13px; padding-inline: 2px;
    font-size: 16px;
    border-bottom: 1px solid var(--line);
  }
  .nav-links a:last-child { border-bottom: none; }
  .nav-links a::after { display: none; }
}
.icon-btn {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--line); border-radius: 12px;
  cursor: pointer;
  transition: border-color 0.2s ease, transform 0.2s ease, background-color 0.35s ease;
}
.icon-btn:hover { border-color: var(--line-2); transform: translateY(-1px); }
.icon-btn:active { transform: translateY(0) scale(0.96); }
.theme-ic { position: absolute; width: 19px; height: 19px; transition: transform 0.45s var(--ease-out), opacity 0.25s ease; }
.theme-ic-sun { opacity: 1; transform: rotate(0deg); }
.theme-ic-moon { opacity: 0; transform: rotate(90deg) scale(0.4); }
:root[data-theme="dark"] .theme-ic-sun { opacity: 0; transform: rotate(-90deg) scale(0.4); }
:root[data-theme="dark"] .theme-ic-moon { opacity: 1; transform: rotate(0deg); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-ic-sun { opacity: 0; transform: rotate(-90deg) scale(0.4); }
  :root:not([data-theme="light"]) .theme-ic-moon { opacity: 1; transform: rotate(0deg); }
}
.menu-btn { display: none; }
@media (max-width: 719px) {
  .menu-btn { display: grid; }
}
.menu-ic { width: 20px; height: 20px; position: relative; }
.menu-ic line { stroke: currentColor; stroke-width: 2; stroke-linecap: round; transition: transform 0.3s var(--ease-out), opacity 0.2s ease; transform-origin: center; }
.nav.open .menu-ic .l1 { transform: translateY(4.5px) rotate(45deg); }
.nav.open .menu-ic .l2 { opacity: 0; }
.nav.open .menu-ic .l3 { transform: translateY(-4.5px) rotate(-45deg); }

/* one glow standard for every button: centered halo at rest, stronger on hover */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-body); font-weight: 700; font-size: 15px;
  border-radius: var(--r-btn); padding: 12px 22px;
  text-decoration: none; border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  box-shadow: 0 0 24px -6px var(--halo);
  transition: transform 0.2s var(--ease-out), box-shadow 0.25s ease, border-color 0.2s ease, background-color 0.25s ease, color 0.25s ease;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
  background: var(--grad-135) border-box; color: var(--btn-fg);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 0 40px -4px var(--halo-strong); }
.btn-ghost {
  background: transparent; color: var(--fg); border-color: var(--line-2);
}
.btn-ghost:hover { border-color: var(--blue); transform: translateY(-2px); box-shadow: 0 0 40px -4px var(--halo-strong); }
.btn-sm { padding: 10px 18px; font-size: 14px; }
.nav .btn-primary { display: inline-flex; }
@media (max-width: 719px) { .nav .btn-primary { display: none; } }

/* ---------- hero ---------- */
.hero {
  position: relative;
  padding-top: clamp(48px, 8vw, 88px);
  padding-bottom: clamp(56px, 8vw, 96px);
  overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0; pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 68%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 68%, transparent 96%);
}
.hero-glow {
  position: absolute; display: block;
  width: min(760px, 110vw); height: min(540px, 80vw);
  border-radius: 50%;
}
.hero-glow-a {
  left: -12%; top: -6%;
  background: radial-gradient(closest-side, var(--glow-2), transparent 72%);
  animation: drift-a 24s ease-in-out infinite alternate;
}
.hero-glow-b {
  right: -14%; bottom: -10%;
  background: radial-gradient(closest-side, var(--glow), transparent 72%);
  animation: drift-b 24s ease-in-out infinite alternate;
}
@keyframes drift-a {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(4%, 7%, 0); }
}
@keyframes drift-b {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-5%, -6%, 0); }
}
.hero-inner {
  position: relative;
  max-width: 1200px; margin: 0 auto;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  display: grid; gap: 40px; align-items: center;
}
@media (min-width: 960px) {
  .hero-inner { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 56px; }
}
.stage {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
}
.logo-frame {
  width: min(100%, 400px);
  aspect-ratio: 325 / 200;
  position: relative;
}
@media (max-width: 719px) {
  .logo-frame { width: 80vw; }
}
.logo-svg {
  position: relative; z-index: 3;
  width: 100%; height: 100%; display: block; overflow: visible;
  /* opacity is driven by the particle script; no CSS transition */
}
.logo-svg.hide { opacity: 0; }
.logo-canvas {
  position: fixed; inset: 0;
  width: 100vw; height: 100vh;
  z-index: 2;
  pointer-events: none;
  display: block;
}
.stage-meta {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  font-family: var(--font-mono); font-size: 12.5px; color: var(--fg-2);
}
.status-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--grad-135); margin-right: 7px;
  box-shadow: 0 0 8px rgba(0, 242, 254, 0.8);
}
.status { font-weight: 500; letter-spacing: 0.02em; }
.chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.chip {
  font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  color: var(--fg-2); background: var(--card);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.chip:hover { border-color: var(--line-2); color: var(--fg); transform: translateY(-1px); }

.hero-copy { position: relative; z-index: 3; min-width: 0; }
.eyebrow {
  font-family: var(--font-mono); font-size: 13px; color: var(--fg-2);
  margin-bottom: 18px; letter-spacing: 0.02em;
}
.eyebrow .prompt { color: var(--blue); font-weight: 600; }
/* a drawn smile instead of ":)" or an emoji, in the text colour */
.nowrap { white-space: nowrap; }
.smile { width: 1.05em; height: 1.05em; vertical-align: -0.18em; margin: 0 0.06em; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.smile .eye { fill: currentColor; stroke: none; }
.eyebrow .path { color: var(--fg); }
.hero-title {
  font-family: var(--font-display);
  font-weight: 800;
  /* smaller than the shared page-title size: the heading is a whole sentence now,
     "Hi, I'm Mohammed — this is my developer portfolio." */
  font-size: clamp(28px, 4.6vw, 48px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0 0 20px;
}
.grad-text {
  display: block;
  background: var(--grad);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.hero-sub {
  max-width: 52ch; font-size: 17px; color: var(--fg-2);
  margin: 0 0 30px;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; }
.hero-note {
  margin-top: 26px; font-family: var(--font-mono); font-size: 12.5px; color: var(--fg-2);
}
.hero-note b { color: var(--fg); font-weight: 600; }

/* hero copy: visible at rest, slides up via keyframes (no script needed) */
.rv { animation: riseIn 0.7s var(--ease-out) backwards; }
@keyframes riseIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---------- sections ---------- */
.section {
  padding-top: clamp(56px, 8vw, 92px);
  padding-bottom: clamp(56px, 8vw, 92px);
}
.section-inner {
  max-width: 1200px; margin: 0 auto;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}
.kicker {
  font-family: var(--font-mono); font-size: 13px; font-weight: 500;
  color: var(--blue); letter-spacing: 0.06em; text-transform: uppercase;
  margin: 0 0 14px;
}
.section-head { max-width: 62ch; margin-bottom: 34px; }
.section-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--t2); letter-spacing: -0.015em; line-height: 1.15;
  margin: 0 0 12px;
}
.section-sub { color: var(--fg-2); font-size: 16px; margin: 0; max-width: 56ch; }


/* reveal: visible at rest, slides up via keyframes when it enters */
.reveal.in { animation: riseIn 0.7s var(--ease-out) backwards; }

/* shared card behaviour: lift + even blue back-light + cursor-following glow */
.app-card, .cv-panel, .contact-panel {
  transition: transform 0.25s var(--ease-out), border-color 0.25s ease, box-shadow 0.3s ease, background-color 0.35s ease;
}
.app-card:hover, .cv-panel:hover, .contact-panel:hover {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px var(--line-2), 0 0 44px -6px var(--halo);
}
.app-card::before, .cv-panel::before, .contact-panel::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(480px 320px at var(--mx, 50%) var(--my, 50%), var(--glow), transparent 70%);
  transition: opacity 0.3s ease;
}
.app-card:hover::before, .cv-panel:hover::before, .contact-panel:hover::before { opacity: 1; }

/* ---------- apps ---------- */
.apps-grid { display: grid; gap: 20px; }
@media (min-width: 800px) { .apps-grid { grid-template-columns: 1fr 1fr; } }
.app-card {
  position: relative; overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 26px;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 14px;
}
.app-card.soon { background: transparent; border-style: dashed; box-shadow: none; justify-content: center; min-height: 240px; }
.app-top { display: flex; align-items: center; gap: 14px; min-width: 0; }
.app-icon-img { padding: 0; overflow: hidden; border: 0; background: none; }
.app-icon-img img { width: 100%; height: 100%; display: block; border-radius: inherit; object-fit: cover; }
.app-icon {
  width: 46px; height: 46px; flex: none;
  border-radius: 13px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  color: var(--fg);
}
.app-icon svg { width: 22px; height: 22px; }
.app-name { font-family: var(--font-display); font-weight: 800; font-size: 19px; letter-spacing: -0.01em; margin: 0; }
.badges { display: flex; flex-wrap: wrap; gap: 8px; }
.badge {
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase;
  border-radius: 999px; padding: 4px 11px; border: 1px solid var(--line);
  color: var(--fg-2); background: var(--card-2);
}
.badge-dev {
  color: var(--blue); border-color: transparent;
  background: var(--glow);
}
.app-desc { margin: 0; color: var(--fg-2); font-size: 15px; max-width: 46ch; }
.app-links { display: flex; flex-wrap: wrap; gap: 18px; margin-top: auto; padding-top: 6px; }
.app-links a {
  font-weight: 700; font-size: 14.5px; text-decoration: none; color: var(--fg);
  display: inline-flex; align-items: center; gap: 5px;
  transition: color 0.2s ease;
}
.app-links a svg { width: 14px; height: 14px; transition: transform 0.2s var(--ease-out); }
.app-links a:hover { color: var(--blue); }
.app-links a:hover svg { transform: translateX(3px); }
/* the "next app" line reads like the hero's terminal line */
.soon-mark {
  font-family: var(--font-mono); font-size: 13px; color: var(--fg-2);
  letter-spacing: 0.02em; margin: 0;
}
.soon-mark .prompt { color: var(--blue); font-weight: 600; }
.soon-mark .path { color: var(--fg); }
/* terminal cursor after the eyebrow and next-app lines */
.cursor-blink { color: var(--blue); font-weight: 600; animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.soon-name { font-family: var(--font-display); font-weight: 800; font-size: 19px; margin: 0; }
.soon-desc { color: var(--fg-2); font-size: 15px; margin: 0; max-width: 40ch; }

/* ---------- cv ---------- */
.cv-panel {
  position: relative; overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: clamp(28px, 5vw, 48px);
}
.cv-grid { display: grid; gap: 36px; align-items: start; }
@media (min-width: 960px) { .cv-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; } }
.cv-copy p { color: var(--fg-2); font-size: 16px; margin: 0 0 18px; max-width: 48ch; }
.cv-copy p b { color: var(--fg); font-weight: 700; }
.cv-list { list-style: none; margin: 22px 0 28px; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.cv-list li { display: flex; gap: 11px; font-size: 15px; color: var(--fg-2); min-width: 0; }
.cv-list li svg { width: 17px; height: 17px; flex: none; margin-top: 3px; color: var(--blue); }

.chat {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.chat-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--card-2);
  transition: background-color 0.35s ease, border-color 0.35s ease;
}
.chat-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--grad-135); flex: none; box-shadow: 0 0 8px rgba(0, 242, 254, 0.7); }
.chat-title { font-family: var(--font-mono); font-size: 13px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* phones: the title may wrap onto a second line instead of being cut off */
@media (max-width: 520px) { .chat-title { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.35; } }
.tag {
  margin-left: auto; flex: none;
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--blue); background: var(--glow); border-radius: 999px; padding: 3px 10px;
}
/* the home demo is a recording: no pointer, no selection, no hover reaction */
.chat.demo { pointer-events: none; user-select: none; -webkit-user-select: none; cursor: default; }
.chat.demo .chat-log { overflow: hidden; }
.chat.demo .msg { max-width: 94%; }
/* phones: the title is long and the "recorded demo" tag long too, so the tag drops to its own line under the title */
@media (max-width: 520px) {
  .chat.demo .chat-head { flex-wrap: wrap; row-gap: 8px; }
  .chat.demo .chat-title { flex: 1 1 calc(100% - 24px); }
  .chat.demo .tag { margin: 0 0 0 19px; }
  [dir="rtl"] .chat.demo .tag { margin: 0 19px 0 0; }
}

/* the one live spot in the recording: the link in the footer, styled like the blue kickers */
.chat.demo .chat-foot a { pointer-events: auto; cursor: pointer; color: var(--blue); text-decoration: underline; text-underline-offset: 3px; }
.chat-log {
  height: 290px; overflow-y: auto;
  padding: 18px; display: flex; flex-direction: column; gap: 12px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
}
.msg { max-width: 82%; min-width: 0; animation: msgIn 0.3s var(--ease-out) both; }
@keyframes msgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.msg.bot { align-self: flex-start; }
.msg.me { align-self: flex-end; }
.bubble {
  border-radius: 14px; padding: 10px 14px;
  font-size: 14.5px; line-height: 1.55;
  overflow-wrap: break-word;
}
.msg.bot .bubble {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-bottom-left-radius: 5px;
}
.msg.me .bubble {
  background: var(--grad-135); color: var(--btn-fg); font-weight: 600;
  border-bottom-right-radius: 5px;
}
.typing { display: inline-flex; gap: 5px; padding: 13px 16px; }
.typing i {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--fg-2); opacity: 0.4;
  animation: tp 1.1s ease infinite;
}
.typing i:nth-child(2) { animation-delay: 0.15s; }
.typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes tp { 30% { transform: translateY(-4px); opacity: 1; } }
.chat-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 18px 0; }
.qchip {
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 500;
  color: var(--fg-2); background: var(--card-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 7px 13px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease, background-color 0.35s ease;
}
.qchip:hover { border-color: var(--blue); color: var(--fg); transform: translateY(-1px); }
.qchip:disabled { opacity: 0.45; cursor: default; transform: none; }
.chat-input { display: flex; gap: 10px; padding: 14px 18px 18px; }
.chat-input input {
  flex: 1; min-width: 0;
  font-family: var(--font-body); font-size: 14.5px;
  color: var(--fg); background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 12px;
  padding: 11px 14px;
  transition: border-color 0.2s ease, background-color 0.35s ease;
}
.chat-input input::placeholder { color: var(--fg-2); }
.chat-input input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--glow); }
.chat-send {
  flex: none; width: 44px;
  border-radius: 12px; border: none; cursor: pointer;
  background: var(--grad-135); color: var(--btn-fg);
  display: grid; place-items: center;
  box-shadow: 0 0 24px -6px var(--halo);
  transition: transform 0.2s var(--ease-out), box-shadow 0.2s ease;
}
.chat-send:hover { transform: translateY(-1px); box-shadow: 0 0 40px -4px var(--halo-strong); }
.chat-send:active { transform: scale(0.94); }
.chat-send svg { width: 17px; height: 17px; }
.chat-foot {
  padding: 0 18px 16px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-2);
}

/* ---------- contact ---------- */
.contact-panel {
  position: relative; overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: clamp(28px, 5vw, 48px);
  display: flex; flex-wrap: wrap; gap: 36px; align-items: center; justify-content: space-between;
}
.contact-left { min-width: min(100%, 380px); }
.contact-left h2 { font-family: var(--font-display); font-weight: 800; font-size: var(--t2); letter-spacing: -0.015em; margin: 0 0 10px; }
.contact-left p { color: var(--fg-2); margin: 0; max-width: 44ch; }
.contact-links { display: flex; flex-direction: column; gap: 12px; min-width: min(100%, 240px); }
.contact-links { flex: 1 1 240px; max-width: 360px; }
.contact-links .btn { gap: 10px; }
.contact-links a span { font-family: var(--font-mono); font-weight: 400; font-size: 12.5px; color: var(--fg-2); }

/* ---------- footer ---------- */
.footer {
  border-top: 1px solid var(--line);
  padding-top: 28px; padding-bottom: 40px;
  transition: border-color 0.35s ease;
}
.footer-inner {
  max-width: 1200px; margin: 0 auto;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px;
}
.footer-brand { display: flex; align-items: center; gap: 9px; font-family: var(--font-display); font-size: 14px; }
.footer-brand b { font-weight: 800; }
.footer-brand span { font-weight: 600; color: var(--fg-2); }
.footer-links { display: flex; gap: 22px; margin-left: auto; }
.footer-links a { font-size: 14px; font-weight: 600; color: var(--fg-2); text-decoration: none; transition: color 0.2s ease; }
.footer-links a:hover { color: var(--fg); }
.footer-copy { width: 100%; font-family: var(--font-mono); font-size: 12px; color: var(--fg-2); }
/* the name lines up with the logo whatever font metrics the phone has:
   in the top bar the text box is trimmed to cap height so flex centring
   centres the letters themselves on the logo tile; in the footer the
   logo sits on the text baseline at letter height. the wordmark keeps
   its Latin font in Arabic too */
.brand-name, .footer-name { font-family: "Montserrat", "Manrope", system-ui, sans-serif; }
.brand-name { text-box: trim-both cap alphabetic; }
.footer-brand { align-items: baseline; direction: ltr; unicode-bidi: isolate; }
.footer-brand svg { height: 0.78em; width: auto; flex: none; }
/* small phones: tighter footer gaps so the links stay beside the name
   (the Arabic link names are wider) */
@media (max-width: 479px) {
  .footer-inner { column-gap: 14px; }
  .footer-links { gap: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .rv, .reveal.in { animation: none; opacity: 1; transform: none; }
  .hero-glow { animation: none; }
  .logo-canvas { display: none; }
}

/* ---------- Arabic ---------- */
.lang-btn { font: 700 16px "IBM Plex Sans Arabic", var(--font-body); }
html[lang="ar"] .lang-btn { font: 700 13px var(--font-body); }
html[lang="ar"] {
  --font-display: "Tajawal", "IBM Plex Sans Arabic", system-ui, sans-serif;
  --font-body: "IBM Plex Sans Arabic", "Tajawal", system-ui, sans-serif;
}
/* Arabic letters join: letter-spacing would break them apart */
html[lang="ar"] body, html[lang="ar"] body * { letter-spacing: normal !important; }
html[lang="ar"] .kicker, html[lang="ar"] .badge { text-transform: none; }
html[lang="ar"] .hero-title { line-height: 1.35; }
/* arrows point the reading direction */
html[dir="rtl"] .app-links svg { transform: scaleX(-1); }
/* code-like bits, addresses and the brand stay left-to-right */
.eyebrow, .brand, .soon-mark, .chat-title, .contact-links a span, .footer-copy { direction: ltr; unicode-bidi: isolate; }
/* dates stay in their written order inside Arabic text (pages mark YYYY-MM-DD dates as <time>) */
time { direction: ltr; unicode-bidi: isolate; }
/* the terminal lines stay left-to-right but sit on the right edge in Arabic */
html[dir="rtl"] .eyebrow, html[dir="rtl"] .soon-mark { text-align: right; }

/* ---------- click effects demo ---------- */
.fx-back, .fx-front { position: fixed; inset: 0; width: 100vw; height: 100vh; pointer-events: none; }
.fx-back { z-index: -1; }
.fx-front { z-index: -1; }  /* glass version: every effect travels behind the cards and shows through the glass */
.fx-layer { position: absolute; left: 0; top: 0; width: 100%; overflow: hidden; pointer-events: none; z-index: -1; }
.fx-bloom {
  position: absolute; pointer-events: none;
  width: 560px; height: 560px; margin: -280px 0 0 -280px; border-radius: 50%;
  background: radial-gradient(closest-side, var(--halo-strong), var(--glow) 45%, transparent 100%);
  animation: fx-bloom 2.8s ease-in-out forwards;
}
@keyframes fx-bloom {
  0% { opacity: 0; transform: scale(0.5); }
  35% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.25); }
}
.fx-pick {
  position: fixed; z-index: 60; left: 50%; transform: translateX(-50%);
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 4px; padding: 5px;
  max-width: calc(100vw - 32px); overflow-x: auto;
  background: color-mix(in srgb, var(--card) 88%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--line-2); border-radius: 999px;
  box-shadow: 0 0 28px -8px var(--halo);
}
.fx-pick-label { font-family: var(--font-mono); font-size: 11px; color: var(--fg-2); padding: 0 8px 0 10px; white-space: nowrap; }
.fx-pick button {
  font-family: var(--font-mono); font-size: 12px; font-weight: 600; white-space: nowrap;
  color: var(--fg-2); background: transparent; border: 0; border-radius: 999px;
  padding: 7px 12px; cursor: pointer; transition: color 0.2s ease, background-color 0.2s ease;
}
.fx-pick button:hover { color: var(--fg); }
.fx-pick button[aria-pressed="true"] { background: var(--grad-135) border-box; color: var(--btn-fg); }
@media (prefers-reduced-motion: reduce) { .fx-back, .fx-front, .fx-bloom { display: none; } }

/* ---------- liquid glass (iOS style) ----------
   clear glass rather than frosted: a very light blur (what travels behind stays visible) with extra saturation and
   brightness, a thick bevelled rim that is brightest at the top-left and
   bottom-right corners, a soft inner glow for thickness, edge refraction
   (Chromium: an SVG lens map bends what is behind the rim, such as the click
   effects travelling under the cards), a specular light
   that follows the cursor, and an elastic, magnetic response */
@property --lg-hot { syntax: "<number>"; inherits: true; initial-value: 0; }
:root {
  --lg-tint: rgba(255, 255, 255, 0.14);
  --lg-edge-a: rgba(255, 255, 255, 0.95);
  --lg-edge-b: rgba(255, 255, 255, 0.22);
  --lg-edge-c: rgba(255, 255, 255, 0.70);
  --lg-inner: rgba(255, 255, 255, 0.45);
  --lg-spec: rgba(255, 255, 255, 0.60);
  --lg-depth: rgba(28, 28, 36, 0.10);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --lg-tint: rgba(255, 255, 255, 0.05);
    --lg-edge-a: rgba(255, 255, 255, 0.55);
    --lg-edge-b: rgba(255, 255, 255, 0.06);
    --lg-edge-c: rgba(255, 255, 255, 0.28);
    --lg-inner: rgba(255, 255, 255, 0.08);
    --lg-spec: rgba(255, 255, 255, 0.15);
    --lg-depth: rgba(0, 0, 0, 0.35);
  }
}
:root[data-theme="dark"] {
  --lg-tint: rgba(255, 255, 255, 0.05);
  --lg-edge-a: rgba(255, 255, 255, 0.55);
  --lg-edge-b: rgba(255, 255, 255, 0.06);
  --lg-edge-c: rgba(255, 255, 255, 0.28);
  --lg-inner: rgba(255, 255, 255, 0.08);
  --lg-spec: rgba(255, 255, 255, 0.15);
  --lg-depth: rgba(0, 0, 0, 0.35);
}

.app-card, .cv-panel, .contact-panel, .chat, .btn, .chat-send { isolation: isolate; --lg-hot: 0; }
.btn, .chat-send { position: relative; }
.app-card:hover, .cv-panel:hover, .contact-panel:hover, .chat:hover, .btn:hover, .chat-send:hover { --lg-hot: 1; }

/* the surface: clear, bright, saturated */
.app-card, .cv-panel, .contact-panel, .btn-ghost, .chat {
  background: var(--lg-tint);
  -webkit-backdrop-filter: blur(3px) saturate(185%) brightness(1.06);
  backdrop-filter: blur(3px) saturate(185%) brightness(1.06);
  border-color: transparent;
  box-shadow: inset 0 0 24px -6px var(--lg-inner), inset 0 -20px 32px -24px var(--lg-depth), var(--shadow);
}
.app-card.soon { background: transparent; box-shadow: inset 0 0 24px -6px var(--lg-inner); }
.app-card:hover, .cv-panel:hover, .contact-panel:hover, .btn-ghost:hover, .chat:hover {
  box-shadow: inset 0 0 24px -6px var(--lg-inner), inset 0 -20px 32px -24px var(--lg-depth), 0 0 44px -6px var(--halo);
}
.btn-primary, .chat-send {
  background: linear-gradient(135deg, rgba(0, 242, 254, 0.78) 0%, rgba(0, 114, 255, 0.78) 100%) border-box;
  -webkit-backdrop-filter: blur(3px) saturate(180%);
  backdrop-filter: blur(3px) saturate(180%);
  border-color: transparent;
  box-shadow: inset 0 0 16px -2px rgba(255, 255, 255, 0.38), inset 0 -10px 16px -10px rgba(0, 30, 90, 0.5), 0 0 24px -6px var(--halo);
}
.btn-primary:hover, .chat-send:hover {
  box-shadow: inset 0 0 16px -2px rgba(255, 255, 255, 0.45), inset 0 -10px 16px -10px rgba(0, 30, 90, 0.5), 0 0 40px -4px var(--halo-strong);
}

/* the chat's title bar is part of the glass too (it was an opaque --card-2 strip): a faint tint
   of the text colour over the glass, so the wallpaper and the cursor light show through, on the
   home teaser and on /cv/ alike */
.chat .chat-head { background: color-mix(in srgb, var(--fg) 4%, transparent); }

/* specular light under the content, following the cursor */
.app-card::before, .cv-panel::before, .contact-panel::before, .chat::before {
  z-index: -1;
  background:
    radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--lg-spec) 100%, transparent) 0%, color-mix(in srgb, var(--lg-spec) 82%, transparent) 12%, color-mix(in srgb, var(--lg-spec) 62%, transparent) 26%, color-mix(in srgb, var(--lg-spec) 42%, transparent) 40%, color-mix(in srgb, var(--lg-spec) 25%, transparent) 55%, color-mix(in srgb, var(--lg-spec) 12%, transparent) 70%, color-mix(in srgb, var(--lg-spec) 4%, transparent) 85%, color-mix(in srgb, var(--lg-spec) 0%, transparent) 100%),
    radial-gradient(520px 360px at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--glow) 100%, transparent) 0%, color-mix(in srgb, var(--glow) 82%, transparent) 12%, color-mix(in srgb, var(--glow) 62%, transparent) 26%, color-mix(in srgb, var(--glow) 42%, transparent) 40%, color-mix(in srgb, var(--glow) 25%, transparent) 55%, color-mix(in srgb, var(--glow) 12%, transparent) 70%, color-mix(in srgb, var(--glow) 4%, transparent) 85%, color-mix(in srgb, var(--glow) 0%, transparent) 100%);
}
/* the chat card is glass too, but the base template never gave it a
   ::before box, so its box and hover reveal live here (the specular
   background, transition, clip and lens come from the card rules) */
.chat::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  opacity: 0;
}
.chat:hover::before { opacity: 1; transition-duration: 0.6s; }
.btn::before, .chat-send::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: radial-gradient(90px circle at var(--mx, 50%) var(--my, 30%), color-mix(in srgb, rgba(255, 255, 255, 0.45) 100%, transparent) 0%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 82%, transparent) 12%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 62%, transparent) 26%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 42%, transparent) 40%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 25%, transparent) 55%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 12%, transparent) 70%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 4%, transparent) 85%, color-mix(in srgb, rgba(255, 255, 255, 0.45) 0%, transparent) 100%);
  opacity: 0; transition: opacity 0.9s cubic-bezier(0.25, 0.1, 0.25, 1);
}
.btn-ghost::before { background: radial-gradient(90px circle at var(--mx, 50%) var(--my, 30%), color-mix(in srgb, var(--lg-spec) 100%, transparent) 0%, color-mix(in srgb, var(--lg-spec) 82%, transparent) 12%, color-mix(in srgb, var(--lg-spec) 62%, transparent) 26%, color-mix(in srgb, var(--lg-spec) 42%, transparent) 40%, color-mix(in srgb, var(--lg-spec) 25%, transparent) 55%, color-mix(in srgb, var(--lg-spec) 12%, transparent) 70%, color-mix(in srgb, var(--lg-spec) 4%, transparent) 85%, color-mix(in srgb, var(--lg-spec) 0%, transparent) 100%); }
.btn:hover::before, .chat-send:hover::before { opacity: 1; transition-duration: 0.6s; }
/* the light fades in gently and fades out a little slower */
.app-card::before, .cv-panel::before, .contact-panel::before, .chat::before { transition: opacity 0.9s cubic-bezier(0.25, 0.1, 0.25, 1); }
.app-card:hover::before, .cv-panel:hover::before, .contact-panel:hover::before { transition-duration: 0.6s; }
.app-card:hover, .cv-panel:hover, .contact-panel:hover, .chat:hover, .btn:hover, .chat-send:hover {
  transition: transform 0.45s cubic-bezier(0.34, 1.28, 0.64, 1), box-shadow 0.3s ease, background-color 0.35s ease, --lg-hot 0.9s cubic-bezier(0.45, 0, 0.25, 1);
}

/* the bevelled rim: bright top-left and bottom-right corners, always on,
   plus a hot spot near the cursor while hovered */
.app-card::after, .cv-panel::after, .contact-panel::after, .chat::after, .btn::after, .chat-send::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  padding: 1.5px;
  background:
    radial-gradient(280px circle at var(--mx, 50%) var(--my, 0%), color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 100%, transparent) 0%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 82%, transparent) 12%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 62%, transparent) 26%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 42%, transparent) 40%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 25%, transparent) 55%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 12%, transparent) 70%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 4%, transparent) 85%, color-mix(in srgb, rgba(255, 255, 255, calc(0.42 * var(--lg-hot))) 0%, transparent) 100%),
    linear-gradient(135deg, var(--lg-edge-a) 0%, var(--lg-edge-b) 28%, var(--lg-edge-b) 72%, var(--lg-edge-c) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.btn-primary::after, .chat-send::after {
  background:
    radial-gradient(170px circle at var(--mx, 50%) var(--my, 0%), color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 100%, transparent) 0%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 82%, transparent) 12%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 62%, transparent) 26%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 42%, transparent) 40%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 25%, transparent) 55%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 12%, transparent) 70%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 4%, transparent) 85%, color-mix(in srgb, rgba(255, 255, 255, calc(0.5 * var(--lg-hot))) 0%, transparent) 100%),
    linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0.15) 30%, rgba(255, 255, 255, 0.15) 70%, rgba(255, 255, 255, 0.55) 100%);
}

/* elastic, magnetic response: pieces lean toward the cursor and settle with
   a spring; pressing squishes them like a drop of liquid */
.app-card, .cv-panel, .contact-panel, .chat, .btn, .chat-send {
  transition: transform 0.45s cubic-bezier(0.34, 1.28, 0.64, 1), box-shadow 0.3s ease, background-color 0.35s ease, --lg-hot 1.1s cubic-bezier(0.45, 0, 0.25, 1);
}
.app-card:hover, .cv-panel:hover, .contact-panel:hover, .chat:hover {
  transform: translate(var(--lx, 0px), calc(var(--ly, 0px) - 2px)) scale(1.005);
}
.btn:hover, .chat-send:hover { transform: translate(var(--lx, 0px), var(--ly, 0px)) scale(1.03); }
.btn:active, .chat-send:active {
  transform: translate(var(--lx, 0px), var(--ly, 0px)) scale(0.97, 0.94);
  transition-duration: 0.12s;
}
@media (prefers-reduced-motion: reduce) {
  .app-card:hover, .cv-panel:hover, .contact-panel:hover, .chat:hover, .btn:hover, .chat-send:hover,
  .btn:active, .chat-send:active { transform: none; }
}

/* the "coming later" card is not glass: just a dotted frame, since the app
   doesn't exist yet. no tint, blur, lens, bevel, sheen or magnetic pull */
.app-card.soon, .app-card.soon:hover {
  background: transparent;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border: 2px dotted color-mix(in srgb, var(--fg) 24%, transparent);
  box-shadow: none;
  transform: none;
}
.app-card.soon:hover { border-color: var(--blue); }
.app-card.soon::before, .app-card.soon::after { display: none; }

/* the glow passes through the edge lens too (set by the script in Chromium) */
.app-card::before, .cv-panel::before, .contact-panel::before, .chat::before,
.btn::before, .chat-send::before { filter: var(--lens-light, none); }

/* ---------- iOS-style pass ----------
   the wallpaper gives the glass something to bend; the rim gets a crisp
   lit edge (top-left strong, bottom-right softer) and a slight darkening
   just inside it, which is what makes a slab of glass read as thick */
:root {
  --lg-hi-1: rgba(255, 255, 255, 0.9);
  --lg-hi-2: rgba(255, 255, 255, 0.55);
  --lg-thick: rgba(10, 40, 90, 0.12);
  --lg-wall-op: 0.75;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --lg-hi-1: rgba(255, 255, 255, 0.38);
    --lg-hi-2: rgba(255, 255, 255, 0.16);
    --lg-thick: rgba(0, 0, 0, 0.28);
    --lg-wall-op: 0.3;
  }
}
:root[data-theme="dark"] {
  --lg-hi-1: rgba(255, 255, 255, 0.38);
  --lg-hi-2: rgba(255, 255, 255, 0.16);
  --lg-thick: rgba(0, 0, 0, 0.28);
  --lg-wall-op: 0.3;
}
.lg-wall {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  opacity: var(--lg-wall-op);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 1000' preserveAspectRatio='xMidYMid slice'%3E %3Cdefs%3E %3ClinearGradient id='a' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%2300F2FE' stop-opacity='.30'/%3E%3Cstop offset='.55' stop-color='%230072FF' stop-opacity='.20'/%3E%3Cstop offset='1' stop-color='%230072FF' stop-opacity='0'/%3E%3C/linearGradient%3E %3ClinearGradient id='b' x1='1' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%230072FF' stop-opacity='.30'/%3E%3Cstop offset='.6' stop-color='%2300F2FE' stop-opacity='.10'/%3E%3Cstop offset='1' stop-color='%2300F2FE' stop-opacity='0'/%3E%3C/linearGradient%3E %3ClinearGradient id='c' x1='0' y1='1' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%2300F2FE' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%2300F2FE' stop-opacity='.22'/%3E%3C/linearGradient%3E %3ClinearGradient id='h' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='.35' stop-color='%23fff' stop-opacity='.30'/%3E%3Cstop offset='.7' stop-color='%23fff' stop-opacity='.12'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='0'/%3E%3C/linearGradient%3E %3Cfilter id='s' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='60'/%3E%3C/filter%3E %3C/defs%3E %3Ccircle cx='300' cy='460' r='260' fill='%2300F2FE' opacity='.08' filter='url(%23s)'/%3E %3Ccircle cx='1260' cy='300' r='300' fill='%230072FF' opacity='.12' filter='url(%23s)'/%3E %3Cpath d='M-80 260C260 120 520 420 860 300C1160 195 1360 60 1700 140L1700 330C1380 250 1180 420 860 470C520 525 260 300-80 420Z' fill='url(%23a)'/%3E %3Cpath d='M-80 260C260 120 520 420 860 300C1160 195 1360 60 1700 140' fill='none' stroke='url(%23h)' stroke-width='2.2'/%3E %3Cpath d='M-80 420C260 300 520 525 860 470C1180 420 1380 250 1700 330' fill='none' stroke='url(%23h)' stroke-width='1.2' opacity='.6'/%3E %3Cpath d='M-80 640C240 520 560 760 900 640C1180 540 1400 470 1700 560L1700 820C1400 720 1160 860 880 900C560 950 240 760-80 880Z' fill='url(%23b)'/%3E %3Cpath d='M-80 640C240 520 560 760 900 640C1180 540 1400 470 1700 560' fill='none' stroke='url(%23h)' stroke-width='2'/%3E %3Cpath d='M-80 700C250 590 560 820 900 700C1180 600 1400 540 1700 620' fill='none' stroke='url(%23h)' stroke-width='1' opacity='.5'/%3E %3Cpath d='M500 1000C700 860 1000 980 1250 860C1400 790 1550 760 1700 790L1700 1000Z' fill='url(%23c)'/%3E %3Cpath d='M500 1000C700 860 1000 980 1250 860C1400 790 1550 760 1700 790' fill='none' stroke='url(%23h)' stroke-width='1.6'/%3E %3C/svg%3E") center / cover no-repeat;
}
.app-card:not(.soon), .cv-panel, .contact-panel, .chat {
  box-shadow: inset 1.5px 1.5px 1px -1px var(--lg-hi-1), inset -1.5px -1.5px 1px -1px var(--lg-hi-2), inset 0 0 18px var(--lg-thick), inset 0 0 24px -6px var(--lg-inner), var(--shadow);
}
.app-card:not(.soon):hover, .cv-panel:hover, .contact-panel:hover, .chat:hover {
  box-shadow: inset 1.5px 1.5px 1px -1px var(--lg-hi-1), inset -1.5px -1.5px 1px -1px var(--lg-hi-2), inset 0 0 18px var(--lg-thick), inset 0 0 24px -6px var(--lg-inner), 0 0 44px -6px var(--halo);
}
.btn-ghost {
  box-shadow: inset 1px 1px 1px -0.5px var(--lg-hi-1), inset -1px -1px 1px -0.5px var(--lg-hi-2), inset 0 0 10px var(--lg-thick), 0 0 24px -6px var(--halo);
}

/* the coming-later frame uses exactly the inner "next_app" box's line:
   1px dashed in the card line colour, turning blue on hover */
.app-card.soon, .app-card.soon:hover { border: 1px dashed var(--line-2); padding: 27px; }
.app-card.soon:hover { border-color: var(--blue); }

/* rounder glass, closer to iOS widgets (the lens and the dotted frame read
   the radius, so they follow) */
.app-card, .cv-panel, .contact-panel, .chat { border-radius: 30px; }

/* wallpaper choices: ribbons (default), silk folds, fine contour lines */
.lg-wall[data-wall="silk"] { background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 1000' preserveAspectRatio='xMidYMid slice'%3E %3Cdefs%3E %3ClinearGradient id='f1' x1='0' y1='0' x2='0.25' y2='1'%3E%3Cstop offset='0' stop-color='%230A2A5C' stop-opacity='0'/%3E%3Cstop offset='.45' stop-color='%231E6FD9' stop-opacity='.55'/%3E%3Cstop offset='.55' stop-color='%237FD8FF' stop-opacity='.55'/%3E%3Cstop offset='.7' stop-color='%230E3C80' stop-opacity='.45'/%3E%3Cstop offset='1' stop-color='%2305142E' stop-opacity='0'/%3E%3C/linearGradient%3E %3ClinearGradient id='f2' x1='0.2' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%2305142E' stop-opacity='0'/%3E%3Cstop offset='.4' stop-color='%2300B8D9' stop-opacity='.35'/%3E%3Cstop offset='.52' stop-color='%23B8F4FF' stop-opacity='.45'/%3E%3Cstop offset='.66' stop-color='%230B4A8A' stop-opacity='.4'/%3E%3Cstop offset='1' stop-color='%2305142E' stop-opacity='0'/%3E%3C/linearGradient%3E %3ClinearGradient id='f3' x1='0' y1='0' x2='0.3' y2='1'%3E%3Cstop offset='0' stop-color='%2305142E' stop-opacity='0'/%3E%3Cstop offset='.5' stop-color='%230072FF' stop-opacity='.4'/%3E%3Cstop offset='.6' stop-color='%238CC8FF' stop-opacity='.35'/%3E%3Cstop offset='1' stop-color='%2305142E' stop-opacity='0'/%3E%3C/linearGradient%3E %3ClinearGradient id='hl' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='.3' stop-color='%23fff' stop-opacity='.55'/%3E%3Cstop offset='.75' stop-color='%23fff' stop-opacity='.25'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='0'/%3E%3C/linearGradient%3E %3Cfilter id='soft' x='-10%25' y='-10%25' width='120%25' height='120%25'%3E%3CfeGaussianBlur stdDeviation='10'/%3E%3C/filter%3E %3C/defs%3E %3Cpath d='M-120 120C220 40 420 380 760 330C1100 280 1250 -20 1720 60L1720 420C1300 340 1150 600 760 640C380 680 200 380-120 470Z' fill='url(%23f1)' filter='url(%23soft)'/%3E %3Cpath d='M-120 300C240 200 420 520 760 485C1120 450 1260 180 1720 240' fill='none' stroke='url(%23hl)' stroke-width='2.4'/%3E %3Cpath d='M-120 560C200 470 520 760 900 700C1240 645 1400 470 1720 520L1720 900C1380 840 1200 1010 880 1020C500 1030 220 820-120 900Z' fill='url(%23f2)' filter='url(%23soft)'/%3E %3Cpath d='M-120 720C220 620 520 900 900 860C1250 820 1400 650 1720 700' fill='none' stroke='url(%23hl)' stroke-width='2'/%3E %3Cpath d='M300 1080C480 900 700 940 980 820C1250 705 1420 760 1720 640L1720 1080Z' fill='url(%23f3)' filter='url(%23soft)'/%3E %3Cpath d='M300 1060C480 900 700 930 980 830C1250 720 1420 770 1720 660' fill='none' stroke='url(%23hl)' stroke-width='1.6' opacity='.8'/%3E %3C/svg%3E") center / cover no-repeat; opacity: calc(var(--lg-wall-op) * 1.6); }
.lg-wall[data-wall="contours"] { background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 1000' preserveAspectRatio='xMidYMid slice'%3E %3Cdefs%3E%3ClinearGradient id='cg' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%2300F2FE'/%3E%3Cstop offset='.5' stop-color='%233AA0FF'/%3E%3Cstop offset='1' stop-color='%230072FF'/%3E%3C/linearGradient%3E%3C/defs%3E %3Cpath d='M-100 -60 L-44 -43 L12 -31 L68 -24 L124 -24 L180 -29 L236 -37 L292 -45 L348 -51 L404 -54 L460 -52 L516 -47 L572 -39 L628 -30 L684 -25 L740 -24 L796 -29 L852 -41 L908 -57 L964 -76 L1020 -94 L1076 -109 L1132 -119 L1188 -121 L1244 -116 L1300 -104 L1356 -89 L1412 -72 L1468 -57 L1524 -46 L1580 -40 L1636 -40 L1692 -44' fill='none' stroke='url(%23cg)' stroke-width='1.6' opacity='0.16' stroke-linejoin='round'/%3E %3Cpath d='M-100 29 L-44 39 L12 43 L68 41 L124 34 L180 25 L236 16 L292 9 L348 5 L404 5 L460 9 L516 13 L572 17 L628 18 L684 14 L740 4 L796 -11 L852 -30 L908 -50 L964 -68 L1020 -82 L1076 -89 L1132 -87 L1188 -78 L1244 -63 L1300 -44 L1356 -24 L1412 -6 L1468 9 L1524 18 L1580 23 L1636 24 L1692 23' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.11' stroke-linejoin='round'/%3E %3Cpath d='M-100 111 L-44 111 L12 107 L68 98 L124 87 L180 77 L236 68 L292 63 L348 60 L404 60 L460 61 L516 60 L572 56 L628 47 L684 34 L740 17 L796 -3 L852 -22 L908 -39 L964 -49 L1020 -53 L1076 -48 L1132 -36 L1188 -18 L1244 2 L1300 24 L1356 44 L1412 60 L1468 71 L1524 79 L1580 84 L1636 88 L1692 92' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.12' stroke-linejoin='round'/%3E %3Cpath d='M-100 177 L-44 168 L12 157 L68 144 L124 132 L180 122 L236 115 L292 110 L348 106 L404 103 L460 98 L516 90 L572 79 L628 65 L684 48 L740 30 L796 13 L852 0 L908 -7 L964 -7 L1020 -0 L1076 13 L1132 31 L1188 51 L1244 71 L1300 90 L1356 106 L1412 117 L1468 126 L1524 133 L1580 139 L1636 147 L1692 157' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.13' stroke-linejoin='round'/%3E %3Cpath d='M-100 222 L-44 209 L12 194 L68 181 L124 170 L180 161 L236 153 L292 148 L348 142 L404 135 L460 126 L516 114 L572 101 L628 86 L684 71 L740 58 L796 49 L852 45 L908 47 L964 54 L1020 67 L1076 82 L1132 100 L1188 117 L1244 132 L1300 145 L1356 155 L1412 163 L1468 170 L1524 177 L1580 186 L1636 196 L1692 209' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.14' stroke-linejoin='round'/%3E %3Cpath d='M-100 253 L-44 238 L12 225 L68 213 L124 203 L180 195 L236 188 L292 181 L348 173 L404 164 L460 154 L516 142 L572 130 L628 118 L684 109 L740 103 L796 101 L852 103 L908 110 L964 120 L1020 132 L1076 145 L1132 158 L1188 169 L1244 179 L1300 187 L1356 193 L1412 199 L1468 206 L1524 214 L1580 224 L1636 235 L1692 249' fill='none' stroke='url(%23cg)' stroke-width='1.6' opacity='0.23' stroke-linejoin='round'/%3E %3Cpath d='M-100 279 L-44 265 L12 254 L68 244 L124 236 L180 229 L236 222 L292 214 L348 206 L404 196 L460 186 L516 176 L572 167 L628 159 L684 155 L740 154 L796 156 L852 161 L908 169 L964 178 L1020 187 L1076 196 L1132 204 L1188 210 L1244 216 L1300 220 L1356 225 L1412 231 L1468 238 L1524 246 L1580 257 L1636 269 L1692 281' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.17' stroke-linejoin='round'/%3E %3Cpath d='M-100 304 L-44 293 L12 284 L68 276 L124 269 L180 262 L236 254 L292 246 L348 237 L404 227 L460 217 L516 209 L572 203 L628 199 L684 198 L740 200 L796 205 L852 212 L908 220 L964 227 L1020 234 L1076 240 L1132 244 L1188 248 L1244 251 L1300 254 L1356 259 L1412 264 L1468 271 L1524 280 L1580 290 L1636 300 L1692 309' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.19' stroke-linejoin='round'/%3E %3Cpath d='M-100 328 L-44 320 L12 312 L68 305 L124 298 L180 290 L236 281 L292 270 L348 260 L404 250 L460 242 L516 236 L572 233 L628 234 L684 238 L740 244 L796 252 L852 261 L908 269 L964 276 L1020 281 L1076 285 L1132 287 L1188 289 L1244 290 L1300 293 L1356 297 L1412 302 L1468 308 L1524 315 L1580 321 L1636 327 L1692 331' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.22' stroke-linejoin='round'/%3E %3Cpath d='M-100 346 L-44 340 L12 333 L68 326 L124 317 L180 307 L236 296 L292 285 L348 274 L404 266 L460 261 L516 261 L572 264 L628 272 L684 282 L740 294 L796 306 L852 316 L908 324 L964 330 L1020 332 L1076 333 L1132 333 L1188 332 L1244 332 L1300 333 L1356 336 L1412 339 L1468 342 L1524 345 L1580 346 L1636 344 L1692 341' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.24' stroke-linejoin='round'/%3E %3Cpath d='M-100 357 L-44 352 L12 346 L68 338 L124 327 L180 316 L236 304 L292 294 L348 287 L404 284 L460 287 L516 295 L572 308 L628 323 L684 340 L740 355 L796 368 L852 377 L908 382 L964 383 L1020 381 L1076 378 L1132 374 L1188 371 L1244 370 L1300 370 L1356 371 L1412 371 L1468 370 L1524 366 L1580 358 L1636 348 L1692 336' fill='none' stroke='url(%23cg)' stroke-width='1.6' opacity='0.40' stroke-linejoin='round'/%3E %3Cpath d='M-100 364 L-44 360 L12 354 L68 345 L124 334 L180 323 L236 314 L292 309 L348 310 L404 318 L460 331 L516 349 L572 369 L628 389 L684 407 L740 421 L796 429 L852 432 L908 430 L964 425 L1020 418 L1076 411 L1132 406 L1188 403 L1244 402 L1300 401 L1356 400 L1412 396 L1468 388 L1524 376 L1580 361 L1636 343 L1692 324' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.29' stroke-linejoin='round'/%3E %3Cpath d='M-100 373 L-44 370 L12 363 L68 354 L124 346 L180 339 L236 338 L292 343 L348 354 L404 372 L460 393 L516 417 L572 439 L628 457 L684 469 L740 475 L796 474 L852 468 L908 460 L964 450 L1020 442 L1076 436 L1132 433 L1188 432 L1244 432 L1300 430 L1356 425 L1412 416 L1468 401 L1524 382 L1580 361 L1636 339 L1692 320' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.30' stroke-linejoin='round'/%3E %3Cpath d='M-100 389 L-44 385 L12 379 L68 373 L124 370 L180 371 L236 379 L292 394 L348 415 L404 438 L460 462 L516 484 L572 500 L628 509 L684 511 L740 507 L796 498 L852 487 L908 476 L964 468 L1020 463 L1076 462 L1132 463 L1188 465 L1244 464 L1300 460 L1356 450 L1412 435 L1468 415 L1524 392 L1580 369 L1636 349 L1692 334' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.32' stroke-linejoin='round'/%3E %3Cpath d='M-100 410 L-44 406 L12 403 L68 403 L124 407 L180 418 L236 435 L292 456 L348 480 L404 503 L460 522 L516 535 L572 541 L628 540 L684 533 L740 522 L796 511 L852 501 L908 494 L964 492 L1020 494 L1076 498 L1132 502 L1188 503 L1244 500 L1300 491 L1356 476 L1412 456 L1468 434 L1524 411 L1580 392 L1636 378 L1692 371' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.32' stroke-linejoin='round'/%3E %3Cpath d='M-100 433 L-44 433 L12 435 L68 442 L124 455 L180 473 L236 495 L292 518 L348 539 L404 556 L460 567 L516 570 L572 567 L628 559 L684 549 L740 539 L796 531 L852 527 L908 528 L964 532 L1020 538 L1076 543 L1132 546 L1188 543 L1244 534 L1300 520 L1356 501 L1412 480 L1468 460 L1524 442 L1580 430 L1636 423 L1692 422' fill='none' stroke='url(%23cg)' stroke-width='1.6' opacity='0.47' stroke-linejoin='round'/%3E %3Cpath d='M-100 462 L-44 467 L12 477 L68 493 L124 512 L180 534 L236 556 L292 575 L348 590 L404 599 L460 602 L516 599 L572 592 L628 583 L684 575 L740 570 L796 568 L852 570 L908 575 L964 581 L1020 586 L1076 587 L1132 584 L1188 575 L1244 561 L1300 543 L1356 525 L1412 507 L1468 493 L1524 483 L1580 479 L1636 479 L1692 481' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.30' stroke-linejoin='round'/%3E %3Cpath d='M-100 503 L-44 516 L12 533 L68 554 L124 576 L180 597 L236 615 L292 629 L348 638 L404 640 L460 638 L516 633 L572 626 L628 620 L684 616 L740 615 L796 616 L852 619 L908 623 L964 625 L1020 623 L1076 618 L1132 608 L1188 595 L1244 580 L1300 565 L1356 551 L1412 541 L1468 535 L1524 534 L1580 537 L1636 541 L1692 545' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.29' stroke-linejoin='round'/%3E %3Cpath d='M-100 563 L-44 582 L12 603 L68 625 L124 646 L180 663 L236 676 L292 684 L348 686 L404 685 L460 680 L516 675 L572 669 L628 664 L684 662 L740 661 L796 660 L852 660 L908 658 L964 654 L1020 646 L1076 637 L1132 625 L1188 613 L1244 601 L1300 593 L1356 588 L1412 587 L1468 590 L1524 596 L1580 603 L1636 610 L1692 614' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.27' stroke-linejoin='round'/%3E %3Cpath d='M-100 642 L-44 663 L12 683 L68 702 L124 717 L180 728 L236 735 L292 736 L348 734 L404 730 L460 723 L516 717 L572 710 L628 705 L684 701 L740 697 L796 692 L852 687 L908 680 L964 672 L1020 663 L1076 654 L1132 646 L1188 639 L1244 636 L1300 637 L1356 641 L1412 648 L1468 658 L1524 668 L1580 678 L1636 685 L1692 689' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.24' stroke-linejoin='round'/%3E %3Cpath d='M-100 731 L-44 748 L12 763 L68 775 L124 783 L180 786 L236 786 L292 782 L348 775 L404 768 L460 759 L516 751 L572 744 L628 737 L684 730 L740 724 L796 717 L852 710 L908 702 L964 695 L1020 688 L1076 684 L1132 682 L1188 683 L1244 689 L1300 697 L1356 708 L1412 721 L1468 734 L1524 746 L1580 755 L1636 761 L1692 764' fill='none' stroke='url(%23cg)' stroke-width='1.6' opacity='0.32' stroke-linejoin='round'/%3E %3Cpath d='M-100 816 L-44 826 L12 833 L68 836 L124 836 L180 831 L236 825 L292 816 L348 806 L404 797 L460 788 L516 780 L572 772 L628 766 L684 760 L740 753 L796 747 L852 741 L908 735 L964 731 L1020 730 L1076 731 L1132 735 L1188 743 L1244 754 L1300 767 L1356 781 L1412 795 L1468 808 L1524 819 L1580 826 L1636 830 L1692 831' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.19' stroke-linejoin='round'/%3E %3Cpath d='M-100 890 L-44 891 L12 889 L68 883 L124 875 L180 865 L236 854 L292 843 L348 833 L404 825 L460 818 L516 812 L572 807 L628 803 L684 798 L740 793 L796 789 L852 784 L908 781 L964 780 L1020 782 L1076 787 L1132 796 L1188 808 L1244 821 L1300 836 L1356 850 L1412 862 L1468 872 L1524 879 L1580 883 L1636 885 L1692 884' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.17' stroke-linejoin='round'/%3E %3Cpath d='M-100 951 L-44 943 L12 932 L68 919 L124 906 L180 892 L236 881 L292 872 L348 865 L404 861 L460 858 L516 856 L572 854 L628 850 L684 846 L740 841 L796 836 L852 832 L908 830 L964 831 L1020 836 L1076 844 L1132 856 L1188 870 L1244 884 L1300 897 L1356 909 L1412 917 L1468 923 L1524 926 L1580 926 L1636 926 L1692 926' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.15' stroke-linejoin='round'/%3E %3Cpath d='M-100 1001 L-44 985 L12 968 L68 951 L124 936 L180 924 L236 915 L292 910 L348 908 L404 908 L460 908 L516 907 L572 904 L628 899 L684 892 L740 885 L796 879 L852 875 L908 874 L964 879 L1020 887 L1076 899 L1132 913 L1188 928 L1244 941 L1300 951 L1356 958 L1412 962 L1468 963 L1524 962 L1580 962 L1636 963 L1692 967' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.14' stroke-linejoin='round'/%3E %3Cpath d='M-100 1044 L-44 1022 L12 1001 L68 984 L124 970 L180 962 L236 958 L292 957 L348 958 L404 959 L460 957 L516 953 L572 945 L628 936 L684 926 L740 917 L796 912 L852 912 L908 916 L964 926 L1020 940 L1076 956 L1132 971 L1188 985 L1244 995 L1300 1000 L1356 1001 L1412 1000 L1468 997 L1524 996 L1580 997 L1636 1003 L1692 1013' fill='none' stroke='url(%23cg)' stroke-width='1.6' opacity='0.19' stroke-linejoin='round'/%3E %3Cpath d='M-100 1076 L-44 1052 L12 1032 L68 1017 L124 1008 L180 1004 L236 1003 L292 1003 L348 1003 L404 1000 L460 993 L516 983 L572 972 L628 960 L684 950 L740 945 L796 946 L852 954 L908 967 L964 984 L1020 1002 L1076 1019 L1132 1033 L1188 1042 L1244 1045 L1300 1043 L1356 1039 L1412 1034 L1468 1030 L1524 1030 L1580 1035 L1636 1046 L1692 1061' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.12' stroke-linejoin='round'/%3E %3Cpath d='M-100 1097 L-44 1075 L12 1059 L68 1049 L124 1044 L180 1043 L236 1042 L292 1040 L348 1035 L404 1026 L460 1015 L516 1002 L572 991 L628 982 L684 980 L740 984 L796 995 L852 1012 L908 1032 L964 1053 L1020 1071 L1076 1084 L1132 1091 L1188 1092 L1244 1087 L1300 1079 L1356 1070 L1412 1063 L1468 1061 L1524 1065 L1580 1073 L1636 1087 L1692 1102' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.11' stroke-linejoin='round'/%3E %3Cpath d='M-100 1109 L-44 1093 L12 1083 L68 1078 L124 1076 L180 1075 L236 1072 L292 1066 L348 1057 L404 1046 L460 1034 L516 1024 L572 1019 L628 1020 L684 1028 L740 1043 L796 1063 L852 1085 L908 1106 L964 1124 L1020 1135 L1076 1139 L1132 1136 L1188 1127 L1244 1115 L1300 1103 L1356 1094 L1412 1089 L1468 1090 L1524 1096 L1580 1106 L1636 1118 L1692 1129' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.11' stroke-linejoin='round'/%3E %3Cpath d='M-100 1120 L-44 1112 L12 1108 L68 1107 L124 1106 L180 1103 L236 1098 L292 1089 L348 1080 L404 1070 L460 1063 L516 1062 L572 1066 L628 1077 L684 1094 L740 1115 L796 1137 L852 1156 L908 1171 L964 1179 L1020 1179 L1076 1172 L1132 1160 L1188 1146 L1244 1132 L1300 1120 L1356 1114 L1412 1112 L1468 1116 L1524 1123 L1580 1131 L1636 1138 L1692 1143' fill='none' stroke='url(%23cg)' stroke-width='1.0' opacity='0.10' stroke-linejoin='round'/%3E%3C/svg%3E") center / cover no-repeat; opacity: calc(var(--lg-wall-op) * 1.5); }
.wall-pick { bottom: calc(62px + env(safe-area-inset-bottom, 0px)); }

/* silk and contours are drawn live on a canvas inside the wallpaper layer */
.lg-wall[data-wall="silk"], .lg-wall[data-wall="contours"] { background: none; }
.lg-wall-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* glass drop: a bead of the same glass, swelling with a spring, then melting.
   it sits just above the wallpaper and behind all text and cards (like the
   other click effects), so it bends only the wallpaper, never the content */
.fx-drop-layer { position: absolute; left: 0; top: 0; width: 100%; overflow: hidden; pointer-events: none; z-index: -1; }
.fx-drop {
  position: absolute; width: 140px; height: 140px; margin: -70px 0 0 -70px; border-radius: 50%;
  background: var(--lg-tint);
  -webkit-backdrop-filter: blur(1.5px) saturate(180%);
  backdrop-filter: blur(1.5px) saturate(180%);
  box-shadow: inset 1.5px 1.5px 1px -1px var(--lg-hi-1), inset -1.5px -1.5px 1px -1px var(--lg-hi-2), inset 0 0 18px var(--lg-thick), 0 12px 30px -14px rgba(0, 0, 0, 0.45);
  animation: fx-drop 2.6s forwards;
}
@keyframes fx-drop {
  0% { transform: scale(0.15); opacity: 0; animation-timing-function: cubic-bezier(0.34, 1.5, 0.64, 1); }
  20% { transform: scale(1); opacity: 1; animation-timing-function: ease-in-out; }
  65% { transform: translateY(-6px) scale(1.03); opacity: 1; animation-timing-function: ease-in; }
  100% { transform: translateY(-16px) scale(1.12); opacity: 0; }
}

/* light wave: each glass piece catches the light as the wave reaches it */
@keyframes lg-flash-hot { 0% { --lg-hot: 0; } 30% { --lg-hot: 1; } 100% { --lg-hot: 0; } }
@keyframes lg-flash-glow { 0% { opacity: 0; } 30% { opacity: 0.9; } 100% { opacity: 0; } }
.lg-flash { animation: lg-flash-hot 1.1s ease-out; }
.reveal.in.lg-flash { animation: riseIn 0.7s var(--ease-out) backwards, lg-flash-hot 1.1s ease-out; }
.lg-flash::before { animation: lg-flash-glow 1.1s ease-out; }
@media (prefers-reduced-motion: reduce) { .fx-drop { display: none; } }

/* the glow is bent by the lens as a rectangle; clip it back to each piece's
   rounded shape, or square corners show (e.g. at the pills' round ends) */
.app-card::before, .cv-panel::before, .contact-panel::before, .chat::before { clip-path: inset(0 round 30px); }
.btn::before { clip-path: inset(0 round 999px); }
.chat-send::before { clip-path: inset(0 round 12px); }

/* ---------- liquid glass logo ---------- */
.logo-pick { bottom: calc(110px + env(safe-area-inset-bottom, 0px)); }
.logo-glass { position: absolute; inset: 0; z-index: 4; pointer-events: none; opacity: 0; transition: opacity 0.9s ease; }
.logo-glass-body, .logo-liquid {
  position: absolute; inset: 0; width: 100%; height: 100%; clip-path: url(#logo-clip);
}
.logo-glass-body {
  background: rgba(255, 255, 255, 0.05);
  -webkit-backdrop-filter: blur(1.5px) saturate(180%) brightness(1.1);
  backdrop-filter: blur(1.5px) saturate(180%) brightness(1.1);
}
.logo-liquid { display: block; }
.logo-glass-rim { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.logo-svg use { transition: opacity 0.9s ease; }
body[data-logo="liquid"] .logo-frame.glass-on .logo-glass { opacity: 1; }
body[data-logo="liquid"] .logo-frame.glass-on .logo-svg use { opacity: 0; }
body[data-logo="liquid"] .logo-frame:not(.glass-on) .logo-svg use { transition: none; }

/* ---------- Customize button and panel ---------- */
.customize-btn {
  display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px;
  border-radius: 999px; border: 1px solid var(--line-2); cursor: pointer;
  background: var(--lg-tint); color: var(--fg);
  font: 600 14px var(--font-body);
  -webkit-backdrop-filter: blur(6px) saturate(170%); backdrop-filter: blur(6px) saturate(170%);
  box-shadow: inset 1px 1px 1px -0.5px var(--lg-hi-1), inset -1px -1px 1px -0.5px var(--lg-hi-2);
  transition: border-color 0.2s ease;
}
.customize-btn:hover, .customize-btn[aria-expanded="true"] { border-color: var(--blue); }
.customize-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
@media (max-width: 719px) { .customize-btn { padding: 0 11px; } .customize-btn .cz-label { display: none; } }
.customize-panel {
  box-sizing: border-box;
  position: fixed; z-index: 70;
  top: calc(var(--nav-h) + 8px + env(safe-area-inset-top, 0px));
  inset-inline-end: max(16px, env(safe-area-inset-right, 0px));
  width: min(360px, calc(100vw - 32px));
  display: flex; flex-direction: column; gap: 16px; padding: 18px;
  border-radius: 22px; border: 1px solid var(--line-2);
  background: color-mix(in srgb, var(--card) 72%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(170%); backdrop-filter: blur(18px) saturate(170%);
  box-shadow: inset 1.5px 1.5px 1px -1px var(--lg-hi-1), inset -1.5px -1.5px 1px -1px var(--lg-hi-2), 0 18px 50px -20px rgba(0, 0, 0, 0.6);
}
.customize-panel[hidden] { display: none; }
.customize-panel .fx-pick {
  position: static; transform: none; left: auto; bottom: auto; max-width: none;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none; overflow: visible;
}
.customize-panel .cz-title {
  width: 100%; padding: 0 2px 2px;
  font: 600 12px var(--font-mono); letter-spacing: 0.04em; color: var(--fg-2);
}
.customize-panel .fx-pick button { border: 1px solid var(--line-2); padding: 8px 14px; font-size: 13px; }
.customize-panel .fx-pick button[aria-pressed="true"] { border-color: transparent; }

/* phones: four round buttons plus the name must fit one row, so the
   buttons get a little smaller and the gaps tighter */
@media (max-width: 719px) {
  .nav-inner { gap: 8px; }
  .nav-actions { gap: 6px; margin-inline-start: auto; }
  .nav-actions .icon-btn, .customize-btn { width: 36px; height: 36px; padding: 0; justify-content: center; border-radius: 11px; }
  .brand { gap: 8px; flex: none; }
  .brand-name { font-size: 15px; white-space: nowrap; }
}
@media (max-width: 359px) {
  .brand-name span { display: none; }
}

/* app icon: shown large inside a small glass tile so the artwork reads */
.app-icon-glass {
  flex: none; width: 80px; height: 80px; padding: 7px; box-sizing: border-box;
  border-radius: 24px; display: grid; place-items: center;
  background: var(--lg-tint);
  -webkit-backdrop-filter: blur(6px) saturate(185%) brightness(1.06);
  backdrop-filter: blur(6px) saturate(185%) brightness(1.06);
  box-shadow: inset 1.5px 1.5px 1px -1px var(--lg-hi-1), inset -1.5px -1.5px 1px -1px var(--lg-hi-2),
    inset 0 0 18px var(--lg-thick), inset 0 0 24px -6px var(--lg-inner), 0 10px 22px -10px rgba(0, 0, 0, 0.45);
}
.app-icon-glass img { width: 100%; height: 100%; display: block; border-radius: 18px; object-fit: cover; }
.app-top:has(.app-icon-glass) { gap: 16px; }

/* badges are frosted glass: half see-through with a blur, so the card glow
   shows softly behind every badge the same way; the "in development" tint
   sits on the same frosted base */
.badge {
  background: color-mix(in srgb, var(--card-2) 55%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.badge-dev { background: linear-gradient(var(--glow), var(--glow)), color-mix(in srgb, var(--card-2) 55%, transparent); }

/* TRIAL 2026-11-10 (owner): the glow that follows the pointer over cards is switched off.
   Covers the soft specular light and the blue glow (the ::before layers of the four card types);
   buttons and the lit card rim are untouched. Backup: ../backups/cursor-glow-before-20261110-192340/.
   To get the glow back, delete this block (or restore lg.css from the backup). */
.app-card::before, .cv-panel::before, .contact-panel::before, .chat::before { display: none; }
