/* utilities.css — the Tailwind subset these templates were written against.
 *
 * Why this file exists
 * --------------------
 * Every template here is authored in Tailwind utility syntax (`text-xs`,
 * `mt-auto`, `gap-3`, `blur-[100px]`), but Tailwind is not loaded. What exists
 * is a hand-written partial subset in styles.css. The result is that some
 * utilities work and some silently do nothing — an audit of the templates found
 * **190 class names used but defined nowhere**, including:
 *
 *   text-xs    83 uses   every card subtitle and meta line fell back to 16px,
 *                        so an 18px heading sat 2px above its own caption and
 *                        the type hierarchy read as flat
 *   w-2 / h-2  19 uses   the terminal "traffic light" dots had no size
 *   bg-*-500   25 uses   ...and no colour
 *   mt-auto     7 uses   card footers did not push to the bottom
 *   ml-auto     4 uses   EXPLORE() / READ() buttons did not right-align
 *   pt-3/pt-4  10 uses   the rule above those footers had no breathing room
 *   blur-[..]  10 uses   the neon glow blobs rendered as hard-edged circles
 *   opacity-*  20 uses   text meant to recede did not
 *
 * That is the "alignment is off everywhere" symptom: not one bad rule, but a
 * vocabulary the markup speaks and the stylesheet does not.
 *
 * Values match Tailwind's defaults exactly, so the existing markup renders the
 * way whoever wrote it expected. Anything Tailwind-shaped that is *already*
 * defined in styles.css is deliberately omitted — this file only fills gaps.
 *
 * Loaded after styles.css and before cyber.css, so component styles still win.
 */

/* ---------------------------------------------------------------- type ---- */
.text-xs   { font-size: 0.75rem;  line-height: 1rem; }
.text-base { font-size: 1rem;     line-height: 1.5rem; }
.text-5xl  { font-size: 3rem;     line-height: 1; }
.text-6xl  { font-size: 3.75rem;  line-height: 1; }

.text-left  { text-align: left; }
.text-right { text-align: right; }

.leading-relaxed { line-height: 1.625; }

.list-disc   { list-style-type: disc; }
.list-inside { list-style-position: inside; }

/* Multi-line clamp. line-clamp-2/-3 already live in bento.css; -1 did not. */
.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ------------------------------------------------------------- spacing ---- */
.p-4 { padding: 1rem; }
.p-5 { padding: 1.25rem; }
.p-6 { padding: 1.5rem; }
.p-8 { padding: 2rem; }

.py-4  { padding-top: 1rem;    padding-bottom: 1rem; }
.py-8  { padding-top: 2rem;    padding-bottom: 2rem; }
.py-20 { padding-top: 5rem;    padding-bottom: 5rem; }
.py-0\.5 { padding-top: 0.125rem; padding-bottom: 0.125rem; }

.px-2\.5 { padding-left: 0.625rem; padding-right: 0.625rem; }
.px-8    { padding-left: 2rem;     padding-right: 2rem; }

.pt-3 { padding-top: 0.75rem; }
.pt-4 { padding-top: 1rem; }
.pl-6  { padding-left: 1.5rem; }
.pl-12 { padding-left: 3rem; }

.mt-1  { margin-top: 0.25rem; }
.mt-10 { margin-top: 2.5rem; }
.mb-1  { margin-bottom: 0.25rem; }
.ml-2  { margin-left: 0.5rem; }
.mr-1  { margin-right: 0.25rem; }

/* The two that quietly broke every card footer. */
.mt-auto { margin-top: auto; }
.ml-auto { margin-left: auto; }

/* ------------------------------------------------------------ flex/gap ---- */
.gap-1    { gap: 0.25rem; }
.gap-1\.5 { gap: 0.375rem; }
.gap-3    { gap: 0.75rem; }
.gap-6    { gap: 1.5rem; }
.gap-x-4  { column-gap: 1rem; }
.gap-y-2  { row-gap: 0.5rem; }

.space-x-2 > * + * { margin-left: 0.5rem; }
.space-y-3 > * + * { margin-top: 0.75rem; }
.space-y-4 > * + * { margin-top: 1rem; }
.space-y-8 > * + * { margin-top: 2rem; }

.flex-shrink-0 { flex-shrink: 0; }
.justify-end   { justify-content: flex-end; }
.inline-block  { display: inline-block; }

/* -------------------------------------------------------------- sizing ---- */
.w-1\.5 { width: 0.375rem; }  .h-1\.5 { height: 0.375rem; }
.w-2    { width: 0.5rem; }    .h-2    { height: 0.5rem; }
.w-2\.5 { width: 0.625rem; }  .h-2\.5 { height: 0.625rem; }
.w-3    { width: 0.75rem; }   .h-3    { height: 0.75rem; }
.w-4    { width: 1rem; }      .h-4    { height: 1rem; }
.w-8    { width: 2rem; }      .h-8    { height: 2rem; }
.w-72   { width: 18rem; }     .h-72   { height: 18rem; }
.w-80   { width: 20rem; }     .h-80   { height: 20rem; }
.w-96   { width: 24rem; }     .h-96   { height: 24rem; }

.h-auto { height: auto; }
.min-h-screen { min-height: 100vh; }
.max-w-5xl { max-width: 64rem; }
.max-w-none { max-width: none; }

/* Required for text truncation inside a flex row: without it the min-content
   width of the text keeps the item from shrinking and the ellipsis never
   appears. Used by the landing page's recent-work rows. */
.min-w-0 { min-width: 0; }

/* ---------------------------------------------------------- positioning --- */
.inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
.top-4    { top: 1rem; }
.right-4  { right: 1rem; }
.bottom-0 { bottom: 0; }
.top-1\/2   { top: 50%; }
.left-1\/2  { left: 50%; }
.left-1\/3  { left: 33.333333%; }
.left-1\/4  { left: 25%; }
.right-1\/3 { right: 33.333333%; }
.right-1\/4 { right: 25%; }
.z-10 { z-index: 10; }

.overflow-hidden { overflow: hidden; }

/* ------------------------------------------------------------ transform --- */
.transform { transform: translate(var(--tw-tx, 0), var(--tw-ty, 0)); }
.-translate-x-1\/2 { --tw-tx: -50%; transform: translate(-50%, var(--tw-ty, 0)); }
.-translate-y-1\/2 { --tw-ty: -50%; transform: translate(var(--tw-tx, 0), -50%); }

.transition-all       { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
.transition-transform { transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); }

/* --------------------------------------------------------------- colour --- */
/* Only the swatches the templates actually name. The -500 set is used for the
   terminal window dots and status pips, which had no colour at all. */
.bg-red-500    { background-color: #ef4444; }
.bg-yellow-500 { background-color: #eab308; }
.bg-green-500  { background-color: #22c55e; }
.bg-cyan-500   { background-color: #06b6d4; }
.bg-purple-500 { background-color: #a855f7; }
.bg-gray-500   { background-color: #6b7280; }
.bg-blue-50    { background-color: #eff6ff; }
.bg-green-50   { background-color: #f0fdf4; }
.text-blue-600 { color: #2563eb; }
.text-transparent { color: transparent; }

.border-current { border-color: currentColor; }
.border-blue-200  { border-color: #bfdbfe; }
.border-green-200 { border-color: #bbf7d0; }
.border-l-4 { border-left-width: 4px; border-left-style: solid; }
.rounded { border-radius: 0.25rem; }

/* -------------------------------------------------------------- effects --- */
.opacity-5  { opacity: 0.05; }
.opacity-10 { opacity: 0.1; }
.opacity-30 { opacity: 0.3; }
.opacity-50 { opacity: 0.5; }
.opacity-60 { opacity: 0.6; }
.opacity-80 { opacity: 0.8; }

/* Arbitrary-value blur: the decorative neon blobs behind each hero. Without
   these they are hard-edged coloured discs rather than a glow. */
.blur-\[100px\] { filter: blur(100px); }
.blur-\[120px\] { filter: blur(120px); }

/* ---------------------------------------------------------------- hover --- */
.hover\:underline:hover { text-decoration: underline; }
.hover\:text-neon-green:hover { color: var(--neon-green); }
.hover\:cyber-text-purple:hover { color: var(--neon-purple); }

@media (prefers-reduced-motion: reduce) {
  .transition-all,
  .transition-transform { transition: none; }
}
