/* PP TECH SOLUTIONS PTY LTD — pptechhub.com
   Plain CSS on purpose: this site has to be droppable onto Hostinger's file
   manager or any static host without a build step.

   Every animation in here is decoration. The page is fully readable with
   motion disabled and with JavaScript off — the reveal states default to
   visible and are only hidden once the observer script confirms it is running,
   so a failed script can never leave the content invisible. */

:root {
  /* Near-black with a blue cast, so the accents read as light rather than paint */
  --ground:        #07080f;
  --ground-2:      #0b0e1a;
  --surface:       #10131f;
  --surface-high:  #151926;

  --edge:          rgba(255, 255, 255, .09);
  --edge-strong:   rgba(255, 255, 255, .16);

  --ink:           #f4f6fb;
  --ink-muted:     #b6bfd4;
  --ink-faint:     #7d8aa6;

  --violet:        #7c5cff;
  --cyan:          #22d3ee;
  --coral:         #fb7185;

  --radius:        18px;
  --radius-sm:     12px;
  --wrap:          1120px;

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

  color-scheme: dark;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A very quiet grain, so the large flat areas do not band on cheap panels. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; position: relative; z-index: 2; }
.wrap.narrow { max-width: 780px; }
.center { text-align: center; }

a { color: var(--cyan); text-decoration-color: rgba(34, 211, 238, .4); text-underline-offset: 3px; }
a:hover { color: #67e8f9; }

.muted { color: var(--ink-faint); }
.small { font-size: .88rem; }

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--violet); color: #fff; padding: 10px 16px; z-index: 20; border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; top: 0; }

:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 4px; }

/* ------------------------------------------------------------- header --- */

.site-header {
  position: sticky; top: 0; z-index: 10;
  background: rgba(7, 8, 15, .6);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.site-header.is-stuck {
  background: rgba(7, 8, 15, .88);
  border-bottom-color: var(--edge);
}
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; min-height: 70px;
}

/* The lockup carries the mark and the wordmark together, so the header no
   longer builds a brand block out of a tile plus two lines of type. */
.brand { display: inline-flex; align-items: center; text-decoration: none; }
.brand img {
  display: block; height: 44px; width: auto;
  transition: transform .35s var(--ease), filter .35s var(--ease);
}
.brand:hover img {
  transform: scale(1.04);
  filter: drop-shadow(0 4px 16px rgba(124, 92, 255, .55));
}

.site-header nav { display: flex; gap: 8px; }
.site-header nav a {
  position: relative;
  color: var(--ink-muted); text-decoration: none;
  font-size: .93rem; font-weight: 500;
  padding: 8px 14px; border-radius: 999px;
  transition: color .25s var(--ease), background .25s var(--ease);
}
.site-header nav a:hover { color: var(--ink); background: rgba(255,255,255,.06); }

/* --------------------------------------------------------------- hero --- */

.hero { position: relative; padding: 110px 0 88px; overflow: hidden; }

/* Three slow-drifting colour fields. Transform-only, so it stays on the
   compositor and does not repaint the text above it. */
.hero::before,
.hero::after,
.hero .aurora {
  content: "";
  position: absolute; border-radius: 50%;
  filter: blur(90px); opacity: .5; pointer-events: none; z-index: 0;
}
.hero::before {
  width: 620px; height: 620px; top: -220px; left: -140px;
  background: radial-gradient(circle, rgba(124,92,255,.85), transparent 68%);
  animation: drift-a 22s var(--ease) infinite alternate;
}
.hero::after {
  width: 560px; height: 560px; top: -140px; right: -160px;
  background: radial-gradient(circle, rgba(34,211,238,.6), transparent 68%);
  animation: drift-b 26s var(--ease) infinite alternate;
}
.hero .aurora {
  width: 460px; height: 460px; bottom: -260px; left: 38%;
  background: radial-gradient(circle, rgba(251,113,133,.42), transparent 68%);
  animation: drift-c 30s var(--ease) infinite alternate;
}
@keyframes drift-a { to { transform: translate3d(120px, 90px, 0) scale(1.15); } }
@keyframes drift-b { to { transform: translate3d(-110px, 70px, 0) scale(1.1); } }
@keyframes drift-c { to { transform: translate3d(90px, -80px, 0) scale(1.18); } }

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  margin: 0 0 20px; padding: 7px 15px 7px 11px;
  border: 1px solid var(--edge); border-radius: 999px;
  background: rgba(255,255,255,.04);
  font-size: .76rem; letter-spacing: 1.3px; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 600;
}
.eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--cyan);
  box-shadow: 0 0 0 0 rgba(34,211,238,.6);
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  70%  { box-shadow: 0 0 0 9px rgba(34,211,238,0); }
  100% { box-shadow: 0 0 0 0 rgba(34,211,238,0); }
}

.hero h1 {
  margin: 0 0 22px;
  font-size: clamp(2.15rem, 5.6vw, 3.6rem);
  line-height: 1.08; letter-spacing: -.03em; font-weight: 800;
  max-width: 17ch;
}
.hero h1 .grad {
  background: linear-gradient(100deg, var(--violet), var(--cyan) 45%, var(--coral) 85%);
  background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: sweep 9s ease-in-out infinite alternate;
}
@keyframes sweep { to { background-position: 100% 0; } }

.lede { margin: 0 0 34px; max-width: 60ch; font-size: 1.1rem; color: var(--ink-muted); }

.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.btn {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 14px 26px; border-radius: 999px;
  text-decoration: none; font-weight: 600; font-size: .96rem;
  border: 1px solid transparent;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), background .3s var(--ease);
}
.btn-primary {
  background: linear-gradient(120deg, var(--violet), #4f46e5 60%, var(--cyan));
  background-size: 200% 100%;
  color: #fff;
  box-shadow: 0 10px 30px -12px rgba(124,92,255,.95);
}
.btn-primary:hover {
  color: #fff; transform: translateY(-2px);
  background-position: 100% 0;
  box-shadow: 0 16px 38px -12px rgba(124,92,255,1);
}
.btn-ghost { border-color: var(--edge-strong); color: var(--ink); background: rgba(255,255,255,.03); }
.btn-ghost:hover { color: var(--ink); background: rgba(255,255,255,.08); transform: translateY(-2px); }
.btn .arrow { transition: transform .3s var(--ease); }
.btn:hover .arrow { transform: translateX(4px); }

/* -------------------------------------------------------------- strip --- */

.strip {
  padding: 70px 0;
  border-top: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
  background: linear-gradient(180deg, var(--ground-2), var(--ground));
}
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.feature {
  padding: 26px 24px;
  border: 1px solid var(--edge); border-radius: var(--radius);
  background: rgba(255,255,255,.022);
  transition: transform .4s var(--ease), border-color .4s var(--ease), background .4s var(--ease);
}
.feature:hover { transform: translateY(-4px); border-color: var(--edge-strong); background: rgba(255,255,255,.045); }
/* Each icon is a finished tile — its own gradient, its own rounded edge — so it
   sits bare. A CSS background or border behind it would only read as a halo. */
.feature .ico {
  display: block;
  width: 48px; height: 48px; margin-bottom: 16px;
  transition: transform .4s var(--ease);
}
.feature:hover .ico { transform: scale(1.08) rotate(-4deg); }
.feature h2 { margin: 0 0 10px; font-size: 1.08rem; letter-spacing: -.015em; }
.feature p { margin: 0; color: var(--ink-muted); font-size: .96rem; }

/* The stack named for anyone who cares, quietly enough that nobody else has to. */
.feature .stack {
  margin-top: 14px; padding-top: 13px;
  border-top: 1px solid var(--edge);
  font-size: .82rem; letter-spacing: .3px; color: var(--ink-faint);
}

/* ------------------------------------------------------------ section --- */

.section { padding: 92px 0; }
.section-alt {
  background: linear-gradient(180deg, var(--ground), var(--ground-2));
  border-top: 1px solid var(--edge); border-bottom: 1px solid var(--edge);
}
.section-title { margin: 0 0 12px; font-size: clamp(1.6rem, 3.4vw, 2.2rem); letter-spacing: -.025em; }
.section-sub { margin: 0 0 40px; color: var(--ink-muted); }

/* --------------------------------------------------------------- apps --- */

.apps { display: grid; grid-template-columns: repeat(2, 1fr); gap: 26px; }

.app-card {
  position: relative;
  padding: 28px 28px 24px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: linear-gradient(165deg, rgba(255,255,255,.055), rgba(255,255,255,.015));
  backdrop-filter: blur(6px);
  transition: transform .45s var(--ease), border-color .45s var(--ease), box-shadow .45s var(--ease);
  overflow: hidden;
}
/* Accent wash that fades up on hover — per-card tint set below. */
.app-card::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: 0; transition: opacity .45s var(--ease);
  background: radial-gradient(520px 200px at 50% -20%, var(--tint, rgba(124,92,255,.3)), transparent 70%);
}
.app-card:hover { transform: translateY(-6px); border-color: var(--edge-strong); box-shadow: 0 26px 60px -30px rgba(0,0,0,.95); }
.app-card:hover::before { opacity: 1; }
.app-card > * { position: relative; z-index: 1; }

.app-card--lizmigo { --tint: rgba(59,130,246,.34); }
.app-card--shabyar { --tint: rgba(236,72,153,.30); }

.app-head { display: flex; align-items: center; gap: 15px; margin-bottom: 18px; }
.app-icon { border-radius: 16px; flex: none; transition: transform .45s var(--ease); }
.app-card:hover .app-icon { transform: scale(1.06) rotate(-3deg); }
.app-head h3 { margin: 0; font-size: 1.28rem; letter-spacing: -.02em; }
.app-tag { margin: 3px 0 0; color: var(--ink-faint); font-size: .9rem; }

.badge {
  margin-left: auto; align-self: flex-start;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 999px;
  font-size: .7rem; font-weight: 700; letter-spacing: .7px; text-transform: uppercase;
  white-space: nowrap;
  background: rgba(255,255,255,.06); border: 1px solid var(--edge-strong); color: var(--ink-muted);
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--cyan); }
.badge--dev .dot { background: var(--coral); }

.app-card > p { margin: 0 0 16px; color: var(--ink-muted); font-size: .97rem; }
.app-points { margin: 0 0 18px; padding: 0; list-style: none; color: var(--ink-muted); font-size: .94rem; }
.app-points li { position: relative; margin: 7px 0; padding-left: 22px; }
.app-points li::before {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 6px; height: 6px; border-radius: 50%;
  background: linear-gradient(135deg, var(--violet), var(--cyan));
}
.app-meta { margin: 0; padding-top: 16px; border-top: 1px solid var(--edge); font-size: .86rem; color: var(--ink-faint); }

/* -------------------------------------------------------------- facts --- */

.facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin: 36px 0 0; }
.facts > div {
  padding: 18px 20px; border: 1px solid var(--edge); border-radius: var(--radius-sm);
  background: rgba(255,255,255,.028);
  transition: transform .35s var(--ease), border-color .35s var(--ease);
}
.facts > div:hover { transform: translateY(-3px); border-color: var(--edge-strong); }
.facts dt { font-size: .7rem; letter-spacing: 1.1px; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 5px; }
.facts dd { margin: 0; font-weight: 600; font-size: .98rem; }

.contact-email { margin: 10px 0 6px; font-size: clamp(1.25rem, 3.4vw, 1.75rem); font-weight: 700; }
.contact-email a {
  background: linear-gradient(100deg, var(--violet), var(--cyan));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  text-decoration: none;
}

/* ------------------------------------------------------------- footer --- */

.site-footer { border-top: 1px solid var(--edge); padding: 46px 0 36px; background: var(--ground-2); }
.footer-inner { display: flex; flex-wrap: wrap; gap: 20px; justify-content: space-between; align-items: flex-start; margin-bottom: 26px; }
.footer-name { margin: 0 0 3px; font-weight: 700; letter-spacing: .3px; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 22px; }
.site-footer nav a { color: var(--ink-muted); text-decoration: none; font-size: .93rem; transition: color .25s var(--ease); }
.site-footer nav a:hover { color: var(--ink); }
.site-footer p { margin: 0; }

/* ------------------------------------------------------ scroll reveals --- */

/* Hidden only once the script adds .js to <html>; without it everything is
   visible, so no-JS and script-error both degrade to a plain readable page. */
.js [data-reveal] { opacity: 0; transform: translateY(22px); }
.js [data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  transition-delay: var(--d, 0ms);
}

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

@media (max-width: 900px) {
  .grid-3 { grid-template-columns: 1fr; gap: 20px; }
  .apps { grid-template-columns: 1fr; }
}

@media (max-width: 580px) {
  body { font-size: 16px; }
  .wrap { padding: 0 18px; }
  .hero { padding: 76px 0 62px; }
  /* The lockup and three links cannot share one row on a phone — how close it
     comes depends on which font actually resolves, which is not something to
     bet the header on. Drop the links onto their own row instead, where the
     width they need stops mattering. */
  .header-inner {
    flex-wrap: wrap; justify-content: center;
    gap: 2px; min-height: 0; padding-top: 10px; padding-bottom: 8px;
  }
  .brand img { height: 34px; }
  /* wrap on the nav too: on a 320px screen the third link would still be
     clipped, and a link that wraps to its own line is better than one that
     disappears. */
  .site-header nav { flex-basis: 100%; flex-wrap: wrap; justify-content: center; gap: 2px; }
  .site-header nav a { font-size: .85rem; padding: 7px 10px; }
  .facts { grid-template-columns: 1fr; }
  .app-head { flex-wrap: wrap; }
  .badge { margin-left: 0; }
  .section { padding: 68px 0; }
}

/* --------------------------------------------------------- reduced motion */

/* Very narrow phones (320px and the like). How wide three nav links actually
   render depends on which font in the stack resolves, and on a 320px screen the
   margin is gone, so trim type and padding until they cannot not fit. */
@media (max-width: 400px) {
  .site-header nav a { font-size: .78rem; padding: 7px 6px; letter-spacing: -.01em; }
  .brand img { height: 30px; }
  .wrap { padding: 0 14px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
  .hero::before, .hero::after, .hero .aurora { animation: none; }
  .btn:hover, .app-card:hover, .feature:hover, .facts > div:hover { transform: none; }
}
