/* ============================================================
   Khairuramdhani — Portfolio
   Light-minimal · navy + gold · scroll-reveal animations
   ============================================================ */

:root {
  --ink:        #15293f;   /* darkest navy — headings */
  --brand:      #1d4e80;   /* primary blue */
  --deep:       #102a43;   /* dark sections */
  --deep-2:     #16395c;   /* dark section gradient stop */
  --gold:       #e2a32a;   /* accent */
  --gold-soft:  #f3c45a;
  --text:       #36475a;   /* body */
  --muted:      #7c8b9a;   /* secondary text */
  --bg:         #ffffff;
  --bg-alt:     #f6f8fc;   /* subtle section bg */
  --card:       #ffffff;
  --card-alt:   #f7f9fc;
  --border:     #e7edf4;
  --shadow-sm:  0 4px 14px rgba(20, 45, 80, .06);
  --shadow-md:  0 12px 34px rgba(20, 45, 80, .10);
  --shadow-lg:  0 26px 60px rgba(16, 42, 67, .16);

  --container: 1160px;
  --radius:    16px;
  --radius-lg: 22px;
  --ease:      cubic-bezier(.22, .61, .36, 1);

  --ff-head: "Poppins", system-ui, sans-serif;
  --ff-body: "Inter", system-ui, sans-serif;

  /* fine grayscale film grain — baked as an SVG so it needs no asset/request */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

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

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

body {
  font-family: var(--ff-body);
  color: var(--text);
  background: var(--bg);
  line-height: 1.65;
  font-size: 16px;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }

/* never let a long word/URL push the layout sideways on narrow phones */
p, li, a, h1, h2, h3, span { overflow-wrap: break-word; }

/* body copy is set ragged-right: justified lines left wide gaps between words */

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  /* keep text clear of the screen edge — and of phone notches/rounded corners */
  padding-left: calc(clamp(1.35rem, 4vw, 2.4rem) + env(safe-area-inset-left, 0px));
  padding-right: calc(clamp(1.35rem, 4vw, 2.4rem) + env(safe-area-inset-right, 0px));
}

h1, h2, h3 { font-family: var(--ff-head); color: var(--ink); line-height: 1.12; letter-spacing: -.02em; }

/* ---------- Scroll progress ---------- */
.progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  background: transparent; z-index: 100;
}
.progress span {
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft));
  transition: width .1s linear;
}

/* ---------- Navbar ---------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  transition: box-shadow .4s var(--ease), padding .4s var(--ease), border-color .4s var(--ease);
  padding: .9rem 0;
  border-bottom: 1px solid rgba(20, 40, 60, .05);
}
/* frosted-glass fill lives on a pseudo-element, not on .nav itself — backdrop-filter
   on .nav would make it a containing block for its position:fixed descendants (the
   mobile menu panel), anchoring that panel to the ~64px nav bar instead of the full
   viewport. Keeping the filter off .nav sidesteps that entirely. */
.nav::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  /* real frosted glass: deep blur + boosted saturation so colours bleed through
     softly (Apple-style), kept translucent so it reads as glass, not white paint */
  background: rgba(255, 255, 255, .55);
  -webkit-backdrop-filter: saturate(180%) blur(30px);
  backdrop-filter: saturate(180%) blur(30px);
  transition: background .4s var(--ease);
}
.nav.scrolled {
  border-bottom-color: rgba(20, 40, 60, .08);
  box-shadow: 0 6px 24px -16px rgba(16, 42, 67, .35);
  padding: .55rem 0;
}
.nav.scrolled::before { background: rgba(255, 255, 255, .68); }
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }

.brand { display: inline-flex; align-items: center; gap: .55rem; font-family: var(--ff-head); font-weight: 700; color: var(--ink); font-size: 1.06rem; }
.brand__star svg { fill: var(--gold); display: block; transition: transform .5s var(--ease); }
.brand:hover .brand__star svg { transform: rotate(90deg); }

.nav__links { display: flex; align-items: center; gap: .35rem; }
.nav__links a {
  font-size: .92rem; font-weight: 500; color: var(--text);
  padding: .5rem .8rem; border-radius: 999px; transition: color .2s, background .2s;
}
.nav__links a:hover { color: var(--brand); }
.nav__links a.active { color: var(--brand); }
.nav__cta {
  background: var(--ink); color: #fff !important; font-weight: 600 !important;
  padding: .55rem 1.1rem !important;
}
.nav__cta:hover { background: var(--brand); }

.nav__toggle { display: none; flex-direction: column; gap: 5px; background: none; border: 0; cursor: pointer; padding: 6px; }
.nav__toggle span { width: 24px; height: 2px; background: var(--ink); border-radius: 2px; transition: .3s var(--ease); }
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Buttons / shared ---------- */
.btn {
  position: relative; display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--ff-head); font-weight: 600; font-size: .95rem;
  padding: .82rem 1.5rem; border-radius: 11px; border: 1.5px solid transparent; cursor: pointer;
  transition: background .2s, border-color .2s, color .2s;
}
.btn--primary { background: var(--ink); color: #fff; }
.btn--primary:hover { background: var(--brand); }
.btn--ghost { background: #fff; color: var(--ink); border-color: #c9d3df; }
.btn--ghost:hover { border-color: var(--ink); }

.eyebrow {
  font-family: var(--ff-head); font-weight: 600; font-size: .78rem;
  letter-spacing: .2em; text-transform: uppercase; color: var(--brand);
  display: inline-flex; align-items: center; gap: .1rem .5rem; flex-wrap: wrap;
}


/* ---------- Sections ---------- */
.section { padding: clamp(4.5rem, 9vw, 8rem) 0; }
.section--alt { background: var(--bg-alt); }
.section__head { margin-bottom: clamp(2.2rem, 5vw, 3.4rem); max-width: 760px; }
.section__head--center { margin-inline: auto; text-align: center; }
.eyebrow .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); }
.eyebrow--gold { color: var(--gold); }
.section__head--center .eyebrow { justify-content: center; }
.section__title { font-size: clamp(2rem, 5vw, 3.1rem); font-weight: 700; margin-top: .9rem; }
.section__lead { color: var(--muted); margin-top: .8rem; font-size: 1.05rem; }

.lead { font-size: 1.12rem; color: var(--text); }
.muted { color: var(--muted); }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex; align-items: center;
  padding: 7rem 0 4rem;
  overflow: hidden;
}
.hero { background: #f4f6f9; }
/* a quiet dot grid, like graph paper, fading out toward the next section */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: radial-gradient(rgba(21, 41, 63, .17) 1px, transparent 1.3px);
  background-size: 22px 22px;
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent);
          mask-image: linear-gradient(to bottom, #000 72%, transparent);
}
.hero__grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1.25fr .75fr; gap: clamp(2rem, 5vw, 4rem);
  align-items: center; width: 100%; max-width: var(--container);
  margin: 0 auto; padding-inline: clamp(1.2rem, 4vw, 2.4rem);
}
.hero__name {
  font-size: clamp(2.1rem, 6vw, 4rem); font-weight: 800; color: var(--ink);
  margin: .4rem 0 .2rem; line-height: 1.02; position: relative;
}

.hero__role { font-family: var(--ff-head); font-weight: 600; font-size: clamp(1.2rem, 3vw, 1.7rem); color: var(--brand); }
.hero__tags { color: var(--muted); margin-top: .55rem; font-size: 1.02rem; }
.hero__tags span { color: var(--gold); margin: 0 .3rem; }
.hero__org { margin: 1.6rem 0; line-height: 1.5; }
.hero__org strong { display: block; font-family: var(--ff-head); color: var(--ink); font-size: 1.05rem; }
.hero__org span { color: var(--muted); font-size: .95rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-bottom: 1.8rem; }
.hero__contact { display: flex; flex-wrap: wrap; gap: .35rem 1.4rem; font-size: .9rem; color: var(--muted); }
.hero__contact a { position: relative; display: inline-flex; align-items: center; gap: .4rem; transition: color .2s; }
.hero__contact svg { fill: currentColor; flex-shrink: 0; }
.hero__contact a:hover { color: var(--brand); }

/* ---------- hero media — lanyard ID card on two live straps (drag → straps follow) ---------- */
.lanyard {
  --card-w: 232px;
  --strap: clamp(96px, 14vh, 160px);
  position: relative; justify-self: center; align-self: start; z-index: 3;
  margin-top: clamp(-2.4rem, -3vw, -1rem);   /* lift the anchors toward the top of the page */
  padding-top: var(--strap);                 /* reserve room for the straps above the card */
  display: flex; flex-direction: column; align-items: center;
  width: var(--card-w); max-width: 88vw;
  -webkit-user-select: none; user-select: none;
  animation: lanyardIn .7s var(--ease) both;
}
@keyframes lanyardIn { from { opacity: 0; } to { opacity: 1; } }

/* the two straps are drawn live in this SVG, so they re-shape as the card is dragged */
.lanyard__ropes { position: absolute; inset: 0; overflow: visible; pointer-events: none; z-index: 1; }
.lanyard__strap { fill: none; stroke: url(#lan-grad); stroke-width: 27; stroke-linejoin: round; stroke-linecap: butt; }
.lanyard__strap--back { stroke: url(#lan-grad-back); }   /* back strap darker → reads behind the front one (depth without a costly filter) */
.lanyard__print { fill: rgba(246, 226, 168, .95); font: 700 10.5px/1 var(--ff-head); letter-spacing: 1.5px; dominant-baseline: middle; text-anchor: middle; }
.lanyard__clip-body { fill: url(#lan-metal); stroke: rgba(58, 70, 86, .35); stroke-width: 1; }
.lanyard__clip-ring { fill: none; stroke: #9aa5b4; stroke-width: 3; }

/* the ID / name card — grab & drag it; the straps above follow */
.lanyard__card {
  position: relative; width: var(--card-w); z-index: 2;
  transform-origin: 50% 0; will-change: transform; touch-action: none; cursor: grab;
  background: linear-gradient(168deg, #ffffff, #eef3f9);
  border: 1px solid #e1e8f0; border-radius: 16px; padding: 15px 15px 13px;
  box-shadow: 0 24px 46px -12px rgba(16, 42, 67, .4), 0 6px 14px -6px rgba(16, 42, 67, .2);
  overflow: hidden;
}
.lanyard.is-grab .lanyard__card { cursor: grabbing; }
.lanyard__card::after {   /* glossy plastic sheen + a highlight that slides with the swing */
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background:
    linear-gradient(125deg, rgba(255, 255, 255, .5) 0 16%, transparent 36%),
    radial-gradient(130% 75% at var(--shine, 46%) -12%, rgba(255, 255, 255, .55), transparent 58%);
  opacity: .6;
}
/* a sharp specular streak that sweeps across the plastic when you grab/drag it */
.lanyard__card::before {
  content: ""; position: absolute; top: -25%; bottom: -25%; left: -40%; width: 38%;
  z-index: 4; pointer-events: none; opacity: 0;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .9), transparent);
  transform: skewX(-18deg) translateX(-220%);
}
.lanyard__card.glint::before { animation: lanGlint .7s var(--ease); }
@keyframes lanGlint {
  0%   { opacity: 0;  transform: skewX(-18deg) translateX(-220%); }
  18%  { opacity: .85; }
  100% { opacity: 0;  transform: skewX(-18deg) translateX(360%); }
}

.lanyard__slot {
  position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
  width: 50px; height: 9px; border-radius: 999px;
  background: #1c2b3d; box-shadow: inset 0 1px 2px rgba(0, 0, 0, .6);
}
.lanyard__head {
  display: flex; align-items: center; gap: .5rem; margin: 13px 0 11px;
  font-family: var(--ff-head); font-size: .6rem; line-height: 1.18;
  letter-spacing: .04em; color: var(--ink); text-transform: uppercase;
}
.lanyard__head > span:first-of-type { flex: 1; font-weight: 700; }
.lanyard__head small { display: block; font-weight: 500; letter-spacing: .02em; color: var(--muted); text-transform: none; }
.lanyard__badge {
  font-weight: 700; font-size: .56rem; letter-spacing: .12em; color: #1b1407;
  background: var(--gold); padding: .16rem .42rem; border-radius: 5px;
}
.lanyard__photo {
  position: relative; border-radius: 11px; overflow: hidden; background: #eef2f6;
  aspect-ratio: 1 / 1; box-shadow: inset 0 0 0 1px rgba(16, 42, 67, .07);
}
.lanyard__photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 100%; transform: scale(1.14); transform-origin: 50% 0; pointer-events: none; }
.lanyard__meta { margin-top: 11px; }
.lanyard__meta strong { display: block; font-family: var(--ff-head); font-weight: 700; color: var(--ink); font-size: 1.08rem; letter-spacing: -.01em; }
.lanyard__meta span { display: block; color: var(--brand); font-weight: 600; font-size: .76rem; font-family: var(--ff-head); }
.lanyard__barcode {
  display: block; height: 22px; margin-top: 11px; border-radius: 3px; opacity: .82;
  background: repeating-linear-gradient(90deg,
    #15293f 0 2px, transparent 2px 4px, #15293f 4px 5px, transparent 5px 9px,
    #15293f 9px 12px, transparent 12px 14px, #15293f 14px 15px, transparent 15px 19px);
}
/* (drag hint removed) */

/* ============================================================
   ABOUT
   ============================================================ */
.about__grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
.about__text p + p { margin-top: 1.1rem; }

/* a small candid aside — photography hobby, paired with a tilted snapshot photo */
.about__hobby { display: flex; align-items: center; gap: 1.2rem; margin-top: 1.5rem; }
.about__hobby-photo { width: 128px; flex-shrink: 0; margin: 0; }
.about__hobby-photo figcaption { font-size: 1.02rem; }
.about__hobby-text { font-size: .95rem; }
@media (max-width: 560px) {
  .about__hobby { flex-direction: column; align-items: flex-start; }
  .about__hobby-photo { width: 150px; }
}
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.stat { border-top: 1px solid #dfe6ee; padding: 1.1rem 0 .4rem; }
.stat__num { font-family: var(--ff-head); font-weight: 800; font-size: 2.6rem; color: var(--gold); line-height: 1; display: block; }
.stat__label { display: block; font-family: var(--ff-head); font-weight: 600; color: var(--ink); font-size: .92rem; margin-top: .5rem; }

/* ============================================================
   SKILLS
   ============================================================ */
.skills__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.4rem 2.6rem; }
.skill-card { border-top: 1px solid #dfe6ee; padding-top: 1.2rem; }
.skill-card h3 { font-size: 1rem; font-weight: 600; margin-bottom: .9rem; }

.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chips li {
  font-family: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, monospace;
  font-size: .8rem; font-weight: 500; color: var(--ink);
  background: #fff; border: 1px solid var(--border);
  padding: .36rem .72rem; border-radius: 8px;
}
.chips--sm li { font-size: .74rem; padding: .3rem .62rem; }

/* ============================================================
   EXPERIENCE
   ============================================================ */
.exp__grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: clamp(2rem, 5vw, 3.5rem); align-items: start; }

.timeline { position: relative; padding-left: 1.8rem; list-style: none; }
.timeline::before {
  content: ""; position: absolute; left: 6px; top: 6px; bottom: 6px; width: 2px;
  background: linear-gradient(var(--gold), var(--border)); border-radius: 2px;
}
.timeline__item { position: relative; padding-bottom: 2.2rem; }
.timeline__item:last-child { padding-bottom: 0; }
.timeline__dot {
  position: absolute; left: -1.8rem; top: 6px; width: 14px; height: 14px;
  background: #fff; border: 3px solid var(--gold); border-radius: 50%; z-index: 1;
}
.timeline__date { font-family: var(--ff-head); font-weight: 600; font-size: .78rem; letter-spacing: .06em; color: var(--gold); text-transform: uppercase; }
.timeline__body h3 { font-size: 1.18rem; font-weight: 600; margin: .35rem 0 .1rem; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.timeline__org { color: var(--brand); font-weight: 500; font-size: .92rem; margin-bottom: .6rem; }
.timeline__body p { font-size: .96rem; }
.timeline__body .chips { margin-top: .9rem; }

.tag { font-family: var(--ff-body); font-size: .68rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--brand); background: #eaf1f9; border: 1px solid #d8e6f4; padding: .18rem .5rem; border-radius: 6px; }
.tag--gold { color: #9a6f12; background: #fbf2dc; border-color: #f0e0b3; }

.checks { margin: .8rem 0; display: grid; gap: .5rem; }
.checks li { position: relative; padding-left: 1.2rem; font-size: .95rem; }
.checks li::before {
  content: ""; position: absolute; left: 0; top: .78em; width: 7px; height: 2px; background: var(--brand);
}

.exp__side { display: grid; gap: 1.4rem; }

/* "printed photo" look — white paper border, handwritten caption, a hint of a tilt,
   like a snapshot taped into a notebook. Straightens up when you hover it. */
.snapshot {
  --tilt: -1.2deg;
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 10px 4px; box-shadow: var(--shadow-md);
  transform: rotate(var(--tilt));
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.snapshot:hover { transform: rotate(0deg) translateY(-3px); box-shadow: var(--shadow-lg); }
.snapshot img { width: 100%; border-radius: 3px; }
.snapshot figcaption {
  font-family: "Caveat", "Segoe Script", cursive;
  font-size: 1.28rem; line-height: 1.2; color: #4a5b6e;
  text-align: center; padding: .55rem .3rem .45rem;
}
/* snapshots that also .reveal: keep the tilt once the reveal lands (the generic
   .reveal.is-visible would otherwise flatten it to transform:none) */
.reveal.snapshot:not(.is-visible) { transform: translateY(28px) rotate(var(--tilt)); }
.reveal.snapshot.is-visible { transform: rotate(var(--tilt)); }
.reveal.snapshot.is-visible:hover { transform: rotate(0deg) translateY(-3px); }

.exp__photo img { aspect-ratio: 3 / 4; object-fit: cover; object-position: center; filter: brightness(1.04) contrast(1.05) saturate(1.03); }

/* photo attached to a timeline entry (e.g. AITF demo day) */
.timeline__photo { --tilt: 1.1deg; margin-top: 1.3rem; max-width: 440px; }
.timeline__photo img { cursor: zoom-in; }

.info-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.4rem; box-shadow: var(--shadow-sm); }
.info-card__title { font-size: 1rem; font-weight: 600; margin-bottom: 1rem; display: flex; gap: .5rem; align-items: baseline; }
.info-item { padding: .55rem 0; border-top: 1px solid var(--border); }
.info-item:first-of-type { border-top: 0; padding-top: 0; }
.info-item strong { display: block; font-family: var(--ff-head); font-weight: 600; color: var(--ink); font-size: .92rem; }
.info-item span { color: var(--muted); font-size: .85rem; }

/* ============================================================
   PROJECTS
   ============================================================ */
.section--dark {
  background: var(--deep);
  color: #cdd8e4;
}
.section--dark .section__title { color: #fff; }
.section--dark .section__lead { color: #9fb2c6; }

.projects { display: grid; gap: 0; margin-top: clamp(2.5rem, 5vw, 4rem); }
/* lets the galleries inside a project scroll instead of widening the page */
.project { min-width: 0; }
/* Urutan proyek mengikuti urutan di index.html (PANDAI, CERDAS, FishFeed, Buah-Seru, ...). */

.project { }
/* Garis pemisah dan judul di atas setiap proyek, supaya galeri satu proyek
   tidak terbaca menyambung dengan gambar proyek berikutnya. */
.project + .project {
  margin-top: clamp(3rem, 6vw, 4.5rem); padding-top: clamp(3rem, 6vw, 4.5rem);
  border-top: 1px solid rgba(255,255,255,.14);
}
.project__head { margin-bottom: clamp(1.25rem, 3vw, 2rem); }
.project__head .project__title { font-size: clamp(2rem, 5vw, 2.9rem); }
.project__head .project__sub { margin-bottom: 0; }
.project__main { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
.project--reverse .project__main { grid-template-columns: 1.1fr .9fr; }
.project--reverse .project__hero { order: 2; }

.project__hero {
  border-radius: var(--radius-lg); overflow: hidden; position: relative;
  background: #0e2740; border: 1px solid rgba(255,255,255,.08);
  box-shadow: var(--shadow-lg);
}
.project__hero img { width: 100%; height: clamp(320px, 38vw, 440px); object-fit: contain; padding: .9rem; }
.project__hero--doc { background: #fff; }
.project__hero--doc img { background: #fff; }
.project__hero figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  font-size: .8rem; color: #e6eef6; padding: 1.4rem 1rem .8rem;
  background: linear-gradient(transparent, rgba(8,22,38,.85)); text-align: center;
}
.project__hero--doc figcaption { color: var(--muted); background: linear-gradient(transparent, #fff 60%); }

.project__no { font-family: var(--ff-head); font-weight: 600; font-size: .82rem; letter-spacing: .12em; text-transform: uppercase; color: var(--gold); display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.project__title { color: #fff; font-size: clamp(1.7rem, 4vw, 2.4rem); font-weight: 700; margin: .4rem 0 .2rem; }
.project__sub { color: #9fb2c6; font-weight: 500; margin-bottom: 1rem; }
.project__info p { color: #c4d2e0; font-size: .98rem; }
.project__info p + p { margin-top: .7rem; }
.project__info .muted { color: #8499ad; font-size: .9rem; }

.section--dark .checks li { color: #c4d2e0; }
.section--dark .checks li::before { background: var(--gold); }
.section--dark .chips--sm li { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.12); color: #dbe6f1; }
.section--dark .chips--sm li:hover { background: var(--gold); border-color: var(--gold); color: #1b1407; }

.repo {
  display: inline-flex; align-items: center; gap: .55rem; margin-top: 1.2rem;
  font-size: .85rem; font-weight: 600; color: #fff;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14);
  padding: .6rem 1rem; border-radius: 999px; transition: background .2s, transform .2s, border-color .2s;
  word-break: break-all;
}
.repo svg { fill: currentColor; flex-shrink: 0; }
.repo:hover { background: var(--gold); color: #1b1407; border-color: var(--gold); transform: translateY(-2px); }

/* documentation gallery */
.docs { margin-top: 2rem; }
.docs__label { font-family: var(--ff-head); font-weight: 600; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: #8aa0b6; margin-bottom: 1rem; }
.docs__label span { color: #5f768c; }
/* each gallery is one row that scrolls sideways and snaps card by card; main.js adds the arrows and captions */
.docs__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.docs__head .docs__label { margin: 0; }
.docs__nav { display: none; gap: .5rem; }
.docs.is-marquee .docs__nav { display: flex; }
.docs__nav button {
  width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  color: #fff; background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .18);
  transition: background .25s, color .25s, border-color .25s, opacity .25s;
}
.docs__nav button:hover:not(:disabled) { background: #fff; color: var(--deep); border-color: #fff; }
.docs__nav button:disabled { opacity: .3; cursor: default; }
.docs__nav svg { width: 16px; height: 16px; }
.docs__grid {
  --card-w: 380px;
  display: flex; gap: 1.1rem; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none; padding-bottom: .25rem;
}
.docs__grid::-webkit-scrollbar { display: none; }
.docs__grid--phone { --card-w: 250px; }
.docs__grid--photo { --card-w: 280px; }
/* with JavaScript the row drifts on its own (main.js): the grid clips a moving strip, and the room above and below
   keeps the lift and shadows from being cut off */
.docs__grid.is-marquee {
  overflow: hidden; scroll-snap-type: none; touch-action: pan-y; cursor: grab;
  padding: 8px 0 34px; margin: -8px 0 -34px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 56px, #000 calc(100% - 56px), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 56px, #000 calc(100% - 56px), transparent);
}
/* a whole-pixel gap keeps every card on the same pixel grid while the strip moves */
.docs__strip { display: flex; gap: 18px; width: max-content; will-change: transform; }
.docs__grid.is-dragging { cursor: grabbing; }
.doc { flex: 0 0 var(--card-w); scroll-snap-align: start; margin: 0; }
.doc__media, .doc > img {
  display: block; width: 100%; aspect-ratio: 4 / 3; border-radius: 14px; overflow: hidden; background: #fff;
  box-shadow: 0 12px 28px rgba(0, 0, 0, .25); cursor: zoom-in; transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
/* phone screenshots already sit in a drawn phone frame, so they stand on the page without a card behind them */
.docs__grid--phone .doc__media, .docs__grid--phone .doc > img { aspect-ratio: 9 / 19; background: none; box-shadow: none; border-radius: 0; overflow: visible; }
.docs__grid--phone .doc__media img, .docs__grid--phone .doc > img { filter: drop-shadow(0 16px 24px rgba(0, 0, 0, .38)); }
.docs__grid--phone .doc:hover .doc__media { box-shadow: none; }
.docs__grid--photo .doc__media, .docs__grid--photo .doc > img { aspect-ratio: 3 / 4; }
.doc__media img, .doc > img { width: 100%; height: 100%; object-fit: contain; display: block; }
.doc__media:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.doc:hover .doc__media { transform: translateY(-4px); box-shadow: 0 18px 36px rgba(0, 0, 0, .32); }
.is-dragging .doc__media { cursor: grabbing; transform: none; }
.doc figcaption { padding: .85rem .1rem 0; font-size: .82rem; line-height: 1.5; color: #9fb2c6; }
.doc figcaption strong { display: block; font: 600 .92rem/1.35 var(--ff-head); color: #fff; }
.doc figcaption strong + span { display: block; margin-top: .3rem; }
@media (max-width: 720px) {
  .docs__grid { --card-w: 80vw; }
  .docs__grid--phone { --card-w: 56vw; }
  .docs__grid--photo { --card-w: 66vw; }
}

/* ============================================================
   CERTIFICATIONS
   ============================================================ */
.certs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.3rem; }
.cert { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); transition: transform .3s var(--ease), box-shadow .3s var(--ease); }
.cert:hover { transform: translateY(-6px); box-shadow: var(--shadow-md); }
.cert__img { background: var(--bg-alt); padding: 1.1rem; }
.cert__img img { width: 100%; aspect-ratio: 4 / 3; object-fit: contain; cursor: zoom-in; }
.cert figcaption { padding: 1rem 1.2rem 1.3rem; }
.cert figcaption strong { display: block; font-family: var(--ff-head); font-weight: 600; color: var(--ink); font-size: .98rem; line-height: 1.35; }
.cert figcaption span { color: var(--muted); font-size: .86rem; }

/* ============================================================
   CONTACT
   ============================================================ */
.section--contact {
  position: relative; color: #d6e2ef; background: #081320;
}
/* Universitas Brawijaya campus backdrop — slow Ken Burns drift + navy overlay */
.contact__bg {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  background: url("assets/ub-campus.jpg") center 30% / cover no-repeat;
  transform: scale(1.08);
  /* lean into the soft source: deliberate bokeh + warm grade */
  filter: blur(3px) saturate(1.18) brightness(.92);
  animation: kenburns 34s ease-in-out infinite alternate;
}
.contact__bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(11, 28, 47, .78), rgba(8, 20, 34, .92));
}
@keyframes kenburns {
  from { transform: scale(1.08) translateY(0); }
  to   { transform: scale(1.17) translateY(-1.5%); }
}
.contact__title { color: #fff; font-size: clamp(2.2rem, 6vw, 3.6rem); font-weight: 700; margin-top: .9rem; }
.contact__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.12); border-radius: var(--radius); overflow: hidden; margin-top: 2.5rem; }
.contact__item { background: rgba(255,255,255,.02); padding: 1.4rem 1.6rem; transition: background .25s; }
.contact__item:hover { background: rgba(226,163,42,.12); }
.contact__k { display: block; font-family: var(--ff-head); font-weight: 600; font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; color: var(--gold); margin-bottom: .35rem; }
.contact__v { color: #eaf1f8; font-size: 1.02rem; overflow-wrap: anywhere; }

/* ---- Contact form ---- */
.contact__form {
  max-width: 680px; margin: 2.2rem auto 0; display: grid; gap: 1.05rem;
  padding: 1.7rem 1.7rem 1.9rem; border-radius: 20px;
  background: rgba(9, 21, 36, .55); border: 1px solid rgba(255, 255, 255, .1);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
}
.form__lead { font-family: var(--ff-head); font-weight: 600; color: #eaf1f8; font-size: 1.06rem; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.05rem; }
.form__field { display: grid; gap: .42rem; }
.form__label { font-family: var(--ff-head); font-weight: 600; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); }
.form__opt { color: #7c8b9a; font-weight: 500; letter-spacing: .04em; text-transform: none; }
.contact__form input[type="text"],
.contact__form input[type="email"],
.contact__form textarea {
  width: 100%; font-family: var(--ff-body); font-size: .98rem; color: #f3f7fb;
  background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 12px; padding: .8rem 1rem;
  transition: border-color .2s, background .2s, box-shadow .2s;
}
.contact__form input::placeholder,
.contact__form textarea::placeholder { color: #6f8398; }
.contact__form input:focus,
.contact__form textarea:focus {
  outline: none; border-color: var(--gold); background: rgba(255, 255, 255, .06);
  box-shadow: 0 0 0 3px rgba(226, 163, 42, .15);
}
.contact__form textarea { resize: vertical; min-height: 120px; }
.form__honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.form__actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.btn--gold { background: var(--gold); color: #1b1407; border: 1.5px solid transparent; box-shadow: 0 8px 20px -10px rgba(226, 163, 42, .7); }
.btn--gold:hover { background: var(--gold-soft); transform: translateY(-2px); box-shadow: 0 14px 26px -10px rgba(226, 163, 42, .6); }
.btn--gold:active { transform: translateY(0); }
.btn--gold[disabled] { opacity: .6; cursor: not-allowed; transform: none; box-shadow: none; }
.form__status { font-size: .92rem; min-height: 1.2em; color: #b9c8d8; }
.form__status.is-ok { color: #7ee0a8; }
.form__status.is-err { color: #ff9b8a; }
@media (max-width: 620px) {
  .form__row { grid-template-columns: 1fr; }
  .contact__form { padding: 1.2rem 1.1rem 1.4rem; }
}

.availability {
  display: inline-flex; align-items: center; gap: .6rem; margin-top: 2rem;
  border: 1px solid rgba(226,163,42,.5); background: rgba(226,163,42,.10);
  color: #f0d9a4; padding: .7rem 1.3rem; border-radius: 999px; font-size: .92rem;
}
.availability__dot { width: 9px; height: 9px; border-radius: 50%; background: #58d68d; box-shadow: 0 0 0 0 rgba(88,214,141,.6); animation: pulse 2s infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(88,214,141,.5); } 70% { box-shadow: 0 0 0 8px rgba(88,214,141,0); } 100% { box-shadow: 0 0 0 0 rgba(88,214,141,0); } }

/* ============================================================
   FOOTER
   ============================================================ */
.footer { background: #0a1c2e; color: #8499ad; padding: 1.6rem 0; }
.footer__inner { display: flex; justify-content: space-between; align-items: center; gap: 1rem; font-size: .88rem; }
.footer__top { color: var(--gold); font-weight: 600; transition: opacity .2s; }
.footer__top:hover { opacity: .75; }

/* ============================================================
   LIGHTBOX
   ============================================================ */
.lightbox {
  position: fixed; inset: 0; z-index: 200; display: none;
  align-items: center; justify-content: center; padding: 4vw;
  background: rgba(8, 18, 30, .92); backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .3s var(--ease);
}
.lightbox.open { display: flex; opacity: 1; }
.lightbox img { display: block; width: auto; height: auto; max-width: 96vw; max-height: 90vh; object-fit: contain; border-radius: 12px; box-shadow: 0 30px 80px rgba(0,0,0,.6); animation: zoomIn .3s var(--ease); background: #fff; }
@keyframes zoomIn { from { transform: scale(.92); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.lightbox__close { position: absolute; top: 1.2rem; right: 1.6rem; background: none; border: 0; color: #fff; font-size: 2.6rem; line-height: 1; cursor: pointer; opacity: .8; transition: opacity .2s; }
.lightbox__close:hover { opacity: 1; }

/* ============================================================
   REVEAL ANIMATIONS
   ============================================================ */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .7s var(--ease), transform .7s var(--ease); will-change: opacity, transform; }
.reveal.is-visible { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .08s; }
.reveal[data-delay="2"] { transition-delay: .16s; }
.reveal[data-delay="3"] { transition-delay: .24s; }
.reveal[data-delay="4"] { transition-delay: .32s; }
.reveal[data-delay="5"] { transition-delay: .40s; }
.reveal[data-delay="6"] { transition-delay: .48s; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 980px) {
  .hero__grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .lanyard { order: -1; margin-top: 0; --strap: clamp(120px, 15vh, 175px); }
  .about__grid,
  .exp__grid { grid-template-columns: 1fr; }
  .project__main,
  .project--reverse .project__main { grid-template-columns: 1fr; }
  .project--reverse .project__hero { order: 0; }
}

/* On phones, let project hero images grow to their natural shape so portrait
   phone screenshots are big & legible instead of squashed into a short box. */
@media (max-width: 760px) {
  .project__hero img { height: auto; max-height: 78vh; padding: .5rem .5rem 2.4rem; }
}

@media (max-width: 760px) {
  .nav__links {
    position: fixed; inset: 0 0 0 auto; width: min(78vw, 320px);
    flex-direction: column; align-items: flex-start; justify-content: center; gap: .4rem;
    background: #fff; padding: 2rem; box-shadow: -10px 0 40px rgba(0,0,0,.12);
    transform: translateX(110%); transition: transform .4s var(--ease);
  }
  .nav__links.open { transform: translateX(0); }
  .nav__links a { width: 100%; font-size: 1.05rem; padding: .7rem .4rem; }
  .nav__cta { text-align: center; margin-top: .5rem; }
  .nav__toggle { display: flex; z-index: 95; }

  .skills__grid { grid-template-columns: 1fr; gap: 1.8rem; }
  .stats { grid-template-columns: 1fr 1fr; }
  .certs { grid-template-columns: 1fr; }
  .contact__grid { grid-template-columns: 1fr; }
  .footer__inner { flex-direction: column; }

  /* gentler slide-in distance so nothing pokes past the screen edge mid-animation */
  .project.reveal:not(.is-visible) { transform: translateX(-24px); }
  .project--reverse.reveal:not(.is-visible) { transform: translateX(24px); }
}

@media (max-width: 420px) {
  .hero__contact { gap: .25rem .9rem; font-size: .82rem; }
  .lanyard { --card-w: 208px; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  /* calm the heavy *looping* ambient motion, but keep the signature one-shot
     entrance (the paper plane writing the name) — that's the page's personality */
  html { scroll-behavior: auto !important; }
  .hero::before, .contact__bg, .availability__dot,
  .section--dark::before, .section--dark::after,
  .lanyard, .brand__star svg { animation: none !important; }
  /* !important so the higher-specificity :not(.is-visible) start-states above
     can never leave content shifted when animations are off */
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* scroll offset so anchored sections clear the fixed nav (≈ nav height + a hair),
   not so much that the heading lands far down the page */
:where(section[id]) { scroll-margin-top: 60px; }

/* ============================================================
   ENHANCED ANIMATIONS — flip cards, tilt, blobs, shine
   ============================================================ */

/* --- flip cards (certificates) --- */
.cert { overflow: visible; background: transparent; border: 0; box-shadow: none; }
.cert:hover { transform: none; box-shadow: none; }
.flip { perspective: 1100px; cursor: pointer; outline: none; }
.flip .flip__inner {
  position: relative; width: 100%; aspect-ratio: 1 / 1;
  transition: transform .8s cubic-bezier(.2, .75, .25, 1); transform-style: preserve-3d;
}
.flip--cert .flip__inner { aspect-ratio: 4 / 3; }
/* Desktop cards preview their details on hover; clicking a certificate opens it in full. */
@media (hover: hover) {
  .flip { cursor: zoom-in; }
  .flip:hover .flip__inner { transform: rotateY(180deg); }
}
.flip:focus-visible .flip__inner { transform: rotateY(180deg); }
/* backface-visibility saja tidak cukup: isi sisi depan yang punya filter
   (latar buram, bayangan) digambar di lapisan GPU sendiri sehingga di
   beberapa browser tetap terlihat terbalik saat kartu diputar. Jadi sisi
   depan juga disembunyikan tepat saat kartu tegak lurus (sekitar 0,12 dtk
   dari 0,8 dtk karena kurvanya cepat di awal). */
.flip__front, .flip__front *, .flip__front::before { backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.flip__front, .flip__back { transition: visibility 0s linear .12s; }
.flip__back { visibility: hidden; }
@media (hover: hover) {
  .flip:hover .flip__front { visibility: hidden; }
  .flip:hover .flip__back { visibility: visible; }
}
.flip:focus-visible .flip__front { visibility: hidden; }
.flip:focus-visible .flip__back { visibility: visible; }
.flip__face {
  position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  border-radius: 14px; overflow: hidden; box-shadow: 0 14px 30px rgba(16, 42, 67, .18);
}
/* one definite grid cell, so the image's height: 100% matches the card instead of overflowing it */
.flip__front { background: #f2f5f9; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; }
.flip--cert .flip__front { background: var(--bg-alt); }
.flip__front img { width: 100%; height: 100%; object-fit: contain; padding: .5rem; }
.flip__front::after {
  content: "\21BB"; position: absolute; top: .45rem; right: .55rem;
  width: 22px; height: 22px; display: grid; place-items: center; font-size: .82rem;
  color: #fff; background: rgba(20, 40, 70, .5); border-radius: 50%;
}
.flip__back {
  transform: rotateY(180deg); background: linear-gradient(155deg, var(--deep-2), var(--deep));
  color: #eaf1f8; border: 1px solid rgba(255, 255, 255, .1);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: .5rem; padding: 1.1rem;
}
.flip__back strong { font-family: var(--ff-head); font-weight: 600; font-size: .92rem; color: #fff; line-height: 1.3; }
.flip__back .issuer { color: var(--gold); font-weight: 600; font-size: .78rem; }
.flip__back span { font-size: .78rem; line-height: 1.5; color: #aebfd1; }

/* --- floating gradient blobs in dark sections --- */
.section--dark, .section--contact { position: relative; overflow: hidden; }
.section--dark > .container, .section--contact > .container { position: relative; z-index: 1; }
.section--dark::before, .section--dark::after,
.section--contact::before, .section--contact::after {
  content: ""; position: absolute; border-radius: 50%; filter: blur(80px); pointer-events: none; z-index: 0;
}
/* no floating colour blobs: the dark and contact sections stay flat */
.section--dark::before, .section--dark::after, .section--contact::before, .section--contact::after { display: none; }

/* --- image zoom on project heroes --- */
.project__hero { transition: box-shadow .35s var(--ease); }
.project__hero img { transition: transform .6s var(--ease); }
.project__hero:hover img { transform: scale(1.05); }

/* --- directional slide-in for projects ---
   scoped to :not(.is-visible): these rules sit after .reveal.is-visible with the
   same specificity, so without the guard they'd win the cascade and pin every
   project at ±46px forever — clipping the whole article on phones */
.project.reveal:not(.is-visible) { transform: translateX(-46px); }
.project--reverse.reveal:not(.is-visible) { transform: translateX(46px); }

/* (button shine-sweep removed — replaced by the tactile press + sliding arrow above) */

@media (prefers-reduced-motion: reduce) {
  .flip__inner, .flip__face, .btn::after, .project__hero img { transition: none !important; }
  .section--dark::before, .section--dark::after,
  .section--contact::before, .section--contact::after { animation: none !important; }
  .project.reveal, .project--reverse.reveal { transform: none !important; }
}

/* ============================================================
   AI ASSISTANT WIDGET (lightweight, in-browser)
   ============================================================ */
.chat-fab {
  position: fixed; right: 22px; bottom: 22px; z-index: 80;
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .82rem 1.25rem; border: 1px solid rgba(243, 196, 90, .45); border-radius: 999px; cursor: pointer;
  font-family: var(--ff-head); font-weight: 700; font-size: .95rem; color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--ink));
  box-shadow: 0 14px 34px rgba(16, 42, 67, .4);
  animation: fabIn .55s var(--ease) .3s backwards, fabPulse 2.8s ease-in-out 1.4s infinite;
  transition: transform .18s var(--ease), box-shadow .25s var(--ease), background .25s;
}
.chat-fab:hover { transform: translateY(-3px) scale(1.05); box-shadow: 0 18px 46px rgba(226, 163, 42, .42); background: linear-gradient(135deg, var(--brand), #0b2138); }
.chat-fab:active { transform: scale(.88); }       /* press: mengecil → lepas: membesar lagi */
.chat-fab.is-open { animation: none; }
.chat-fab svg { fill: var(--gold); flex: 0 0 auto; }
@keyframes fabIn { from { opacity: 0; transform: translateY(26px) scale(.5); } to { opacity: 1; transform: none; } }
@keyframes fabPulse {
  0%, 100% { box-shadow: 0 14px 34px rgba(16, 42, 67, .4), 0 0 0 0 rgba(226, 163, 42, .5); }
  50%      { box-shadow: 0 14px 34px rgba(16, 42, 67, .4), 0 0 0 15px rgba(226, 163, 42, 0); }
}

/* tactile press feedback on buttons (grow on release) */
.repo:active, .chat-form button:active, .chat-chips button:active, .chat-panel__close:active { transform: scale(.92); }

/* themed scrollbars — page + chat (no more grey/white default) */
html { scrollbar-width: thin; scrollbar-color: #c2cedd transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #c6d2e0; border-radius: 10px; border: 3px solid #fff; }
::-webkit-scrollbar-thumb:hover { background: #a7b8cb; }
.chat-log { scrollbar-width: thin; scrollbar-color: rgba(226, 163, 42, .5) transparent; }
.chat-log::-webkit-scrollbar { width: 8px; }
.chat-log::-webkit-scrollbar-track { background: transparent; }
.chat-log::-webkit-scrollbar-thumb { background: rgba(226, 163, 42, .42); border: none; border-radius: 8px; }
.chat-log::-webkit-scrollbar-thumb:hover { background: rgba(226, 163, 42, .65); }

.chat-panel {
  position: fixed; right: 20px; bottom: 20px; z-index: 90;
  width: min(380px, calc(100vw - 32px)); height: min(560px, calc(100vh - 40px));
  display: flex; flex-direction: column; overflow: hidden;
  background: #0c1f33; color: #e9f1f9;
  border: 1px solid rgba(255, 255, 255, .12); border-radius: 20px;
  box-shadow: 0 30px 70px rgba(0, 0, 0, .5);
  opacity: 0; transform: translateY(20px) scale(.96); pointer-events: none;
  transition: opacity .28s var(--ease), transform .28s var(--ease);
}
.chat-panel.open { opacity: 1; transform: none; pointer-events: auto; }
.chat-panel__head {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .85rem 1rem; border-bottom: 1px solid rgba(255, 255, 255, .1);
  background: linear-gradient(135deg, var(--deep-2), var(--deep));
}
.chat-panel__id { display: flex; align-items: center; gap: .6rem; }
.chat-panel__avatar {
  width: 34px; height: 34px; display: grid; place-items: center; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: #fff; font-size: .9rem; font-weight: 700;
}
.chat-panel__id strong { display: block; font-family: var(--ff-head); font-size: .95rem; }
.chat-panel__sub { font-size: .72rem; color: #8aa0b6; }
.chat-panel__close { background: none; border: none; color: #aebfd1; font-size: 1.6rem; line-height: 1; cursor: pointer; padding: 0 .15rem; }
.chat-panel__close:hover { color: #fff; }

.chat-log { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .55rem; }
.chat-msg {
  max-width: 85%; padding: .6rem .85rem; border-radius: 14px; font-size: .9rem;
  line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere;
}
.chat-msg--bot { align-self: flex-start; background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .08); border-bottom-left-radius: 4px; }
.chat-msg--user { align-self: flex-end; background: var(--brand); color: #fff; border-bottom-right-radius: 4px; }
.chat-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .15rem; }
.chat-chips button {
  font-family: var(--ff-body); font-size: .8rem; color: var(--gold); cursor: pointer;
  background: rgba(226, 163, 42, .1); border: 1px solid rgba(226, 163, 42, .35);
  border-radius: 999px; padding: .35rem .7rem; transition: background .2s;
}
.chat-chips button:hover { background: rgba(226, 163, 42, .22); }

.chat-form { display: flex; gap: .5rem; padding: .7rem; border-top: 1px solid rgba(255, 255, 255, .1); }
.chat-form input {
  flex: 1; min-width: 0; font-family: var(--ff-body); font-size: .9rem; color: #f3f7fb;
  background: rgba(255, 255, 255, .06); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 12px; padding: .6rem .85rem;
}
.chat-form input:focus { outline: none; border-color: var(--gold); }
.chat-form input::placeholder { color: #6f8398; }
.chat-form button { flex: 0 0 auto; width: 42px; border: none; border-radius: 12px; background: var(--gold); color: #1b1407; font-size: 1rem; cursor: pointer; }
.chat-foot { font-size: .67rem; color: #6f8398; text-align: center; padding: 0 .7rem .6rem; }

@media (max-width: 480px) {
  .chat-fab__label { display: none; }
  .chat-fab { padding: .8rem; right: 14px; bottom: 14px; }
  .chat-panel { right: 8px; bottom: 8px; width: calc(100vw - 16px); height: calc(100dvh - 80px); }
}
@media (prefers-reduced-motion: reduce) { .chat-panel { transition: none; } }

/* shown only in the printed/PDF CV, hidden on the live site */
.print-only { display: none; }

/* ============================================================
   PRINT / PDF  (open with ?print or #print, then "Save as PDF")
   ============================================================ */
@media print {
  @page { margin: 12mm; }
  .print-only { display: block !important; }
  .hero__printlink { font-size: .92rem; color: #1d4e80 !important; margin-top: .6rem; }
  .hero__printlink a { color: #1d4e80 !important; text-decoration: underline; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .progress, .nav, .lightbox, .footer__top, .flip__front::after, .hero__actions,
  .contact__form, .contact__bg, .chat-fab, .chat-panel { display: none !important; }
  html { scroll-behavior: auto; }
  body { color: #1a2733; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .section, .hero { padding: 1.1rem 0 !important; min-height: auto !important; }
  .hero { padding-top: .4rem !important; }

  /* lanyard: drop the straps on paper, show the card flat & upright */
  .lanyard { margin-top: 0 !important; padding-top: 0 !important; }
  .lanyard__ropes, .lanyard__slot, .lanyard__barcode, .lanyard__card::after { display: none !important; }
  .lanyard__card { transform: none !important; }
  .lanyard__photo img { transform: none !important; }

  /* light, ink-friendly backgrounds */
  .section--alt, .section--dark, .section--contact { background: #fff !important; color: #1a2733 !important; }
  .section--dark::before, .section--dark::after,
  .section--contact::before, .section--contact::after { display: none !important; }
  .section--dark .section__title, .contact__title, .project__title { color: #15293f !important; }
  .section--dark .section__lead, .project__sub, .project__info p, .project__info .muted { color: #44545f !important; }
  .contact__item { background: #f4f6f9 !important; }
  .contact__v { color: #1a2733 !important; }
  .repo { color: #15293f !important; background: none !important; border-color: #cbd5e0 !important; }
  .repo svg { fill: #15293f !important; }
  .section--dark .chips--sm li { background: #f0f3f7 !important; color: #1a2733 !important; border-color: #dde3ea !important; }

  /* flip cards -> show image + explanation stacked */
  .flip .flip__inner { transform: none !important; aspect-ratio: auto !important; }
  .flip__face { position: static !important; backface-visibility: visible !important; box-shadow: none !important; border: 0 !important; visibility: visible !important; }
  .flip__front { background: #fff !important; }
  .flip__front img { height: auto !important; max-height: 280px; }
  .flip__back { transform: none !important; background: none !important; color: #333 !important;
    align-items: flex-start; text-align: left; padding: .3rem 0 0 !important; gap: .15rem; }
  .flip__back strong { color: #15293f !important; }
  .flip__back .issuer { color: #9a6f12 !important; }
  .flip__back span { color: #44545f !important; }

  /* snapshots: print flat & straight, keep the paper border */
  .snapshot { transform: none !important; box-shadow: none !important; }
  .timeline__photo { max-width: 300px; }

  /* keep the web design's structure & accents on paper */
  .skill-card, .cert, .stat, .info-card, .doc, .timeline__item, .lanyard__card, .snapshot {
    border: 1px solid #e3e9f1 !important; box-shadow: none !important; border-radius: 10px !important;
  }
  .eyebrow, .eyebrow--gold, .timeline__date, .project__no, .docs__label { color: #b07d12 !important; }
  .section__title, .hero__name, .about__text strong { color: #15293f !important; }
  .hero__role { color: #1d4e80 !important; }
  .tag, .chips li, .chips--sm li { background: #eef2f8 !important; color: #1d4e80 !important; border: 1px solid #dde5ef !important; }
  .stat__num { color: #1d4e80 !important; }

  /* avoid ugly page breaks */
  .project, .skill-card, .cert, .doc, .timeline__item, .stat, .info-card, .snapshot { break-inside: avoid; }
  .project + .project { border-top-color: #d5dde4 !important; }
  h2, .section__head, .project__no, .project__title { break-after: avoid; }
  .project__main, .project--reverse .project__main { grid-template-columns: 1fr 1.3fr !important; }
  .project--reverse .project__hero { order: 0; }
  img { max-width: 100% !important; }
}

/* ============================================================
   VIDEO (YouTube, dimuat saat diklik)
   ============================================================ */
.video-embed {
  position: relative; width: 100%; max-width: 860px; aspect-ratio: 16 / 9; margin-inline: auto;
  border-radius: 14px; overflow: hidden; background: #000;
  box-shadow: 0 10px 26px rgba(0,0,0,.22);
}
.video-embed iframe,
.video-embed__poster { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-embed__notice { position: absolute; inset: 0; display: grid; place-items: center; padding: 1.5rem; text-align: center; color: #dbe6f1; background: #0b1f33; font-size: .95rem; }
.video-embed__poster { padding: 0; margin: 0; cursor: pointer; background: #000; display: block; }
.video-embed__poster img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .4s var(--ease), opacity .3s; }
.video-embed__poster:hover img { transform: scale(1.03); opacity: .88; }
.video-embed__play {
  position: absolute; left: 50%; top: 50%; width: 76px; height: 76px; transform: translate(-50%, -50%);
  border-radius: 50%; background: var(--gold); box-shadow: 0 8px 24px rgba(0,0,0,.35);
  transition: transform .25s var(--ease);
}
.video-embed__play::after {
  content: ""; position: absolute; left: 31px; top: 23px;
  border-style: solid; border-width: 15px 0 15px 24px; border-color: transparent transparent transparent var(--ink);
}
.video-embed__poster:hover .video-embed__play,
.video-embed__poster:focus-visible .video-embed__play { transform: translate(-50%, -50%) scale(1.08); }
.video-embed__poster:focus-visible { outline: 3px solid var(--gold-soft); outline-offset: -3px; }
.video-embed__link { margin-top: .7rem; font-size: .85rem; text-align: center; }
.docs--video .docs__label { text-align: center; }
.video-embed__link a { color: var(--gold-soft); font-weight: 600; text-decoration: none; }
.video-embed__link a:hover { text-decoration: underline; }
.video-embed__link span { color: #8aa0b6; font-weight: 400; }

/* Foto mendatar tersendiri di bawah galeri ponsel, selebar video */
.docs--wide .docs__label { text-align: center; }
.docs__wide { max-width: 860px; margin-inline: auto; border-radius: 14px; overflow: hidden; background: #0b1f33; box-shadow: 0 10px 26px rgba(0,0,0,.22); }
.docs__wide img { display: block; width: 100%; height: auto; cursor: zoom-in; }
.docs__wide figcaption { font-size: .82rem; color: #dbe6f1; text-align: center; padding: .7rem 1rem; }
.docs__wide figcaption span { color: #8aa0b6; }



/* ---------- Project media: demo videos, sticky media column, one language at a time ---------- */
.project__main { align-items: start; }
@media (min-width: 901px) {
  .project__hero { position: sticky; top: 96px; }
}
.project__hero--video {
  display: flex; flex-direction: column; align-items: center;
  padding: 1.4rem 1rem .9rem; background: #fff;
}
.project__hero--video video {
  display: block; height: clamp(430px, 46vw, 580px); width: auto; aspect-ratio: 360 / 778; background: #fff;
}
.project__hero--video figcaption { position: static; background: none; color: var(--muted); padding: .7rem .5rem 0; }
.project__hero--video:hover img { transform: none; }
.demo-video__toggle {
  position: absolute; top: 14px; right: 14px; width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid rgba(15, 37, 57, .12); background: rgba(15, 37, 57, .78); cursor: pointer;
  display: grid; place-items: center; transition: background .25s var(--ease), transform .25s var(--ease);
}
.demo-video__toggle:hover { background: rgba(226, 163, 42, .9); transform: scale(1.06); }
.demo-video__toggle span { width: 12px; height: 14px; border-left: 4px solid #fff; border-right: 4px solid #fff; }
.demo-video__toggle.is-paused span {
  width: 0; height: 0; border: 0; border-left: 13px solid #fff;
  border-top: 8px solid transparent; border-bottom: 8px solid transparent; margin-left: 4px;
}

/* teks proyek ditampilkan dalam satu bahasa sekaligus; tombol EN/ID di navigasi mengganti bahasanya */
.lang-toggle {
  position: relative; display: inline-flex; padding: 3px; border-radius: 999px; border: 1px solid rgba(15, 37, 57, .15);
  background: rgba(255, 255, 255, .7); cursor: pointer; font: 600 .78rem var(--ff-head); margin-right: .4rem;
}
.lang-toggle::before {
  content: ""; position: absolute; top: 3px; bottom: 3px; left: 3px; width: 2.6rem; border-radius: 999px;
  background: var(--ink); transition: transform .42s cubic-bezier(.3, .8, .25, 1);
}
.lang-toggle[data-lang="id"]::before { transform: translateX(100%); }
.lang-toggle span { position: relative; width: 2.6rem; padding: .3rem 0; text-align: center; color: var(--muted); transition: color .3s; }
.lang-toggle:not([data-lang="id"]) [data-l="en"], .lang-toggle[data-lang="id"] [data-l="id"] { color: #fff; }
/* language switch (main.js): the page blurs and dims while a card names the new language */
.lang-veil {
  position: fixed; inset: 0; z-index: 300; display: grid; place-items: center; pointer-events: none; opacity: 0;
  background: rgba(9, 22, 36, .62); -webkit-backdrop-filter: blur(22px) saturate(110%); backdrop-filter: blur(22px) saturate(110%);
  transition: opacity .34s ease;
}
.lang-veil.is-on { opacity: 1; pointer-events: auto; }
.lang-veil__card {
  display: grid; justify-items: center; gap: .3rem; min-width: 210px; padding: 1.5rem 2.4rem 1.35rem; border-radius: 22px;
  background: rgba(255, 255, 255, .97); box-shadow: 0 30px 70px rgba(4, 14, 26, .35);
  opacity: 0; transform: translateY(10px) scale(.94); transition: opacity .3s ease, transform .45s cubic-bezier(.2, .8, .2, 1);
}
.lang-veil.is-on .lang-veil__card { opacity: 1; transform: none; transition-delay: .1s; }
.lang-veil__code { font: 700 2.6rem/1 var(--ff-head); letter-spacing: .06em; color: var(--ink); }
.lang-veil__name { font: 500 .95rem var(--ff-body); color: var(--muted); }
body:not(.lang-id) .project__info p.muted { display: none; }
body.lang-id .project__info p:not(.muted) { display: none; }
body.lang-id .project__info p.muted { color: #c4d2e0; font-size: .98rem; }

@media (prefers-reduced-motion: reduce) {
  .doc__media, .demo-video__toggle { transition: none; }
}

/* teks panjang tidak boleh menabrak kolom gambar */
.project__info { min-width: 0; }
.repo { overflow-wrap: anywhere; }
.project__info p { max-width: 62ch; }
body:not(.lang-id) .lang-id, body.lang-id .lang-en { display: none; }

/* video demo dan logo aplikasi berdampingan di kartu putih */
/* the video fills the left column; the app details and the play/pause button stack in the middle of the right one */
.video-pair {
  display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: 1fr auto auto 1fr; align-items: center;
  column-gap: clamp(1rem, 2.5vw, 1.8rem); row-gap: 0; width: 100%;
}
.video-pair video { height: clamp(400px, 40vw, 540px); grid-column: 1; grid-row: 1 / -1; }
.video-pair__brand { grid-column: 2; grid-row: 2; }
.video-pair { position: relative; }
.video-pair__brand { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .35rem; padding-right: .4rem; }
/* the logo opts out of the padding and fixed height that .project__hero img gives the other card images */
.video-pair__brand img { width: clamp(72px, 8vw, 108px); height: auto; max-height: none; padding: 0; border-radius: 22%; }
.video-pair__brand strong { font-family: var(--ff-head); font-size: 1.45rem; color: var(--ink); letter-spacing: .02em; margin-top: .4rem; }
.video-pair__brand span { font-size: .8rem; color: var(--muted); line-height: 1.35; max-width: 18ch; }
.video-pair__brand em { font-style: normal; font-size: .72rem; font-weight: 600; color: #1b6b4e; background: #e6f4ee; padding: .25rem .65rem; border-radius: 12px; margin-top: .35rem; }
/* play and pause sit under the app details as a labelled button instead of on top of the video */
.video-pair .demo-video__toggle {
  grid-column: 2; grid-row: 3; justify-self: center; position: static; width: auto; height: 34px; margin-top: .9rem;
  padding: 0 .95rem 0 .8rem; gap: .5rem; display: inline-flex; align-items: center; border-radius: 999px;
  border: 1px solid rgba(15, 37, 57, .16); background: #fff; color: var(--ink); font: 600 .76rem var(--ff-head);
}
.video-pair .demo-video__toggle:hover { background: var(--ink); color: #fff; transform: none; }
.video-pair .demo-video__toggle span { width: 9px; height: 11px; border-left: 3px solid currentColor; border-right: 3px solid currentColor; }
.video-pair .demo-video__toggle.is-paused span { width: 0; height: 0; border-left: 9px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent; border-right: 0; margin-left: 2px; }
.video-pair .demo-video__toggle::after { content: "Pause demo"; }
.video-pair .demo-video__toggle.is-paused::after { content: "Play demo"; }
body.lang-id .video-pair .demo-video__toggle::after { content: "Jeda demo"; }
body.lang-id .video-pair .demo-video__toggle.is-paused::after { content: "Putar demo"; }
@media (max-width: 560px) {
  /* phones: app name on top, then the video, then the play/pause button right under it */
  .video-pair { grid-template-columns: 1fr; grid-template-rows: none; justify-items: center; }
  .video-pair video, .video-pair__brand, .video-pair .demo-video__toggle { grid-column: auto; grid-row: auto; }
  .video-pair__brand { order: -1; flex-direction: row; gap: .7rem; text-align: left; align-items: center; margin-bottom: .9rem; }
  .video-pair__brand img { width: 56px; }
  .video-pair__brand strong { margin-top: 0; line-height: 1; }
  .video-pair__brand span, .video-pair__brand em { display: none; }
}
