repo split: move projects to their own repos as submodules; bulk data purged to Gitea-Storage (Jupiter)

This commit is contained in:
2026-06-18 19:02:53 -07:00
parent d5bfe76780
commit 4fcd3088af
1266 changed files with 80 additions and 198742 deletions

60
.gitmodules vendored
View File

@@ -10,3 +10,63 @@
path = projects/youtube-sync-docker
url = https://git.azcomputerguru.com/azcomputerguru/youtube-sync-docker.git
branch = main
[submodule "projects/acg-website-showcase"]
path = projects/acg-website-showcase
url = https://git.azcomputerguru.com/azcomputerguru/acg-website-showcase.git
[submodule "projects/community-forum"]
path = projects/community-forum
url = https://git.azcomputerguru.com/azcomputerguru/acg-community-forum.git
[submodule "projects/dataforth-dos"]
path = projects/dataforth-dos
url = https://git.azcomputerguru.com/azcomputerguru/dataforth-dos.git
[submodule "projects/discord-bot"]
path = projects/discord-bot
url = https://git.azcomputerguru.com/azcomputerguru/acg-discord-bot.git
[submodule "projects/graphifyy-eval"]
path = projects/graphifyy-eval
url = https://git.azcomputerguru.com/azcomputerguru/graphifyy-eval.git
[submodule "projects/gururmm-agent"]
path = projects/gururmm-agent
url = https://git.azcomputerguru.com/azcomputerguru/gururmm-agent.git
[submodule "projects/internal"]
path = projects/internal
url = https://git.azcomputerguru.com/azcomputerguru/acg-internal-projects.git
[submodule "projects/msp-pricing"]
path = projects/msp-pricing
url = https://git.azcomputerguru.com/azcomputerguru/msp-pricing.git
[submodule "projects/newsletter"]
path = projects/newsletter
url = https://git.azcomputerguru.com/azcomputerguru/acg-newsletter.git
[submodule "projects/radio-show"]
path = projects/radio-show
url = https://git.azcomputerguru.com/azcomputerguru/radio-show.git
[submodule "projects/wrightstown-smarthome"]
path = projects/wrightstown-smarthome
url = https://git.azcomputerguru.com/azcomputerguru/wrightstown-smarthome.git
[submodule "projects/wrightstown-solar"]
path = projects/wrightstown-solar
url = https://git.azcomputerguru.com/azcomputerguru/wrightstown-solar.git
[submodule "projects/msp-tools/guru-scan"]
path = projects/msp-tools/guru-scan
url = https://git.azcomputerguru.com/azcomputerguru/guru-scan.git
[submodule "projects/msp-tools/msp-audit-scripts"]
path = projects/msp-tools/msp-audit-scripts
url = https://git.azcomputerguru.com/azcomputerguru/msp-audit-scripts.git
[submodule "projects/msp-tools/quote-wizard"]
path = projects/msp-tools/quote-wizard
url = https://git.azcomputerguru.com/azcomputerguru/quote-wizard.git
[submodule "projects/msp-tools/research"]
path = projects/msp-tools/research
url = https://git.azcomputerguru.com/azcomputerguru/msp-research.git
[submodule "projects/msp-tools/scripts"]
path = projects/msp-tools/scripts
url = https://git.azcomputerguru.com/azcomputerguru/msp-scripts.git
[submodule "projects/msp-tools/security-assessment"]
path = projects/msp-tools/security-assessment
url = https://git.azcomputerguru.com/azcomputerguru/security-assessment.git
[submodule "projects/msp-tools/toolkit"]
path = projects/msp-tools/toolkit
url = https://git.azcomputerguru.com/azcomputerguru/msp-toolkit.git
[submodule "projects/msp-tools/utilities"]
path = projects/msp-tools/utilities
url = https://git.azcomputerguru.com/azcomputerguru/msp-utilities.git

View File

@@ -1,35 +0,0 @@
# Arizona Computer Guru — Website Showcase
Single-page, hand-built static site (HTML/CSS/vanilla JS). A local "what we can do" showcase.
## Art direction: SONORAN LEDGER
Chosen by Grok+Gemini design panel (both ranked #1), confirmed by Mike (human review 2026-06-14).
Concept: a trusted local bookkeeper's ledger for the web. Pricing, the calculator, and the
concierge story are treated as a permanent, transparent record — the design embodiment of
"honest numbers, no games." Warm paper, precise rules, mono numerals.
## Design system (locked)
- **Light:** paper `#F7F3EB`, surface `#EDE6D9`, ink `#2A2521`, ink-2 `#5A5148`.
- **Dark:** paper `#1C1814`, surface `#2A2520`, ink `#E8DFCE`, ink-2 `#C4B8A3`.
- **Accent (the "ink"):** amber `#F2922E` for marks/underlines/button fill (dark text on it).
- Orange-on-cream TEXT fails AA at the bright value → orange text/links on light use `#BD5A00`.
- On dark, accent text uses `#F2A24E` (passes AA on `#1C1814`).
- **Type:** Barlow Condensed (600700) display + "since 2001" lockup; Lexend body;
JetBrains Mono for ALL prices, calculator output, endpoint counts.
- **Baseline:** strict 24px vertical rhythm. Faint ledger rulings align to Lexend line-height.
- **Radius:** 02px only. Sharp = precise/manual.
## Anti-slop rules (Gemini, non-negotiable)
1. Orange = highlighting ink — active data, underlines, primary CTA only. Never big blocks/generic icons.
2. Zero generic iconography (no FontAwesome/Heroicons). CSS-drawn precision marks / hardware photos only.
3. Ledger grid — everything snaps to 24px baseline; rulings align to body line-height.
4. Data as design — calculator is the centerpiece, not a popup. Large mono "stamped" totals.
5. No over-smoothed radius — sharp corners.
## Pipeline
Grok (imagery + direction input) → Gemini (design weight) → human pick → build →
multi-AI design+code review → human-touch review → publish locally.
## Content integrity
No fabricated named testimonials (prior site flagged this as a launch blocker). Proof is built
on verifiable facts; any testimonial slot is clearly marked representative.

View File

@@ -1,64 +0,0 @@
# Arizona Computer Guru — Website Showcase
Multipage marketing site for Arizona Computer Guru. Hand-built static (HTML/CSS/vanilla JS).
3 design skins, Bold as default. **Live deployment:** http://ww9.azcomputerguru.com
**Active version:** `multipage/` (6 pages: Home, Services, Pricing, Calculator, About, Contact)
**Default design:** Bold — premium brutalist with Anton headlines, signal orange, grayscale photos
**Archived:** Single-page Sonoran Ledger version (root `index.html`) — kept as reference pattern
## View it
**Live site:** http://ww9.azcomputerguru.com (deployed to IX hosting, grey-cloud Cloudflare DNS)
**Local preview:**
```bash
cd multipage/
powershell -ExecutionPolicy Bypass -File serve.ps1 # port 4328
# OR
py -m http.server 4328
```
**Archived single-page (Sonoran Ledger):**
```bash
# From project root
powershell -ExecutionPolicy Bypass -File serve.ps1 # port 4327
```
## What's inside
**Multipage (active):** `multipage/`
- 6 HTML pages (index, services, pricing, calculator, about, contact)
- 3 skins: **Bold** (default), Midnight, Verdigris — each with light + dark themes
- Bold design: Anton uppercase headlines, signal orange (#E24A12), grayscale photos, bone/near-black palette
- `css/styles.css` — 3-skin token-based system
- `js/app.js` — theme + skin switchers, calculator, mobile nav, FAQ
- `assets/images/` — Grok photography (default warm set + Verdigris cool set)
- `PRODUCT.md`, `DESIGN.md` — brand register + design rules
**Single-page (archived):** Root directory
- `index.html` — Sonoran Ledger design (warm paper aesthetic)
- Kept as reusable pattern for other Guru-related sites
## Features
- **3 design skins** with header switcher (Bold / Midnight / Verdigris)
- **Light + dark themes** for each skin (system-aware, remembered, FOUC-free)
- **Interactive IT cost calculator** — GPS tiers, support plans, M365, phones → monthly/annual totals
- **Estimate handoff** — calculator builds statement for contact form
- Published GPS pricing, services, FAQ
- WCAG-AA contrast in all 6 modes; keyboard-accessible nav, FAQ, forms
- **Grayscale photography** in Bold skin (color in Midnight/Verdigris)
## Deployment
- **Production:** http://ww9.azcomputerguru.com
- **Server:** IX Web Hosting (ix.azcomputerguru.com, 72.194.62.5)
- **Path:** `/home/azcomputerguru/public_html/ww9/`
- **DNS:** Cloudflare A record (grey cloud / DNS-only)
- **HTTPS:** AutoSSL (Let's Encrypt, auto-provisioned)
Contact forms are demo only (not wired). Pricing illustrative of published GPS rates.
## History
- 2026-06-16: Deployed to ww9.azcomputerguru.com; Paper/Ledger skin dropped, Bold set as default
- 2026-06-14-15: Built multipage (4 skins), Bold skin added as dialed-back radical
- 2026-06-14: Built single-page Sonoran Ledger via Grok+Gemini pipeline

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,94 +0,0 @@
Copyright (c) 2010-2015, Łukasz Dziedzic (dziedzic@typoland.com),
with Reserved Font Name Lato.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -1,72 +0,0 @@
Lato font family (Desktop version)
==================================
Version 2.015; Latin+Cyrillic+Greek+IPA opensource
Created by: tyPoland Lukasz Dziedzic
Creation year: 2015
Copyright (c) 2010-2015 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.
Lato is a trademark of tyPoland Lukasz Dziedzic.
Source URL: http://www.latofonts.com/
License URL: http://scripts.sil.org/OFL
================
Lato is a sanserif typeface family designed in the Summer 2010 and extended in the Summer 2013 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in the 2010s, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness. In 2013-2014, the family was greatly extended (with the help of Adam Twardoch and Botio Nikoltchev) to cover 3000+ glyphs over nine weights with italics. It now supports 100+ Latin-based languages, 50+ Cyrillic-based languages as well as Greek and IPA phonetics. The Lato fonts are available free of charge under the SIL Open Font License from http://www.latofonts.com/
================
CONTENTS:
This folder contains 18 font files in OpenType TT (.ttf) format. You can install these fonts on your computer and use in any desktop applications (such as Word, InDesign, Illustrator, Photoshop, Keynote or Pages).
================
REVISION LOG:
# Version 2.015 (2015-08-06)
Initial implementation of mark positioning (should work for most glyphs)
Autohinted using ttfautohint 1.3.
# Version 2.010 (2014-09-01)
Improved some contour bugs and diacritics positioning.
Improved outline quality.
Revised OTL features so that they work in browsers (ot-sanitise).
Autohinted using ttfautohint 1.1.
Interpolated the Medium weight differently so it provides more visual difference from Regular.
# Version 2.007 (2014-02-27)
Greatly expanded character set, revised metrics, four additional weights.
# Version 1.104 (2011-11-08)
Merged the distribution again
Autohinted with updated ttfautohint 0.4 (which no longer causes Adobe and iOS problems)
except the Hai and Lig weights which are hinted in FLS 5.1.
# Version 1.102 (2011-10-28)
Added OpenType Layout features
Ssplit between desktop and web versions
Desktop version: all weights autohinted with FontLab Studio
Web version autohinted with ttfautohint 0.4 except the Hai and Lig weights
# Version 1.101 (2011-09-30)
Fixed OS/2 table Unicode and codepage entries
# Version 1.100 (2011-09-12)
Added Polish diacritics to the character set
Weights Hai and Lig autohinted with FontLab Studio
Other weights autohinted with ttfautohint 0.3
# Version 1.011 (2010-12-29)
Added the soft hyphen glyph
# Version 1.010 (2010-12-13)
Initial version released under SIL Open Font License
Western character set
================

View File

@@ -1,25 +0,0 @@
# ACG Brand Kit
Forward-relevant Arizona Computer Guru brand assets, curated from the master
"Branding Stuff" archive on 2026-06-15. Legacy/bulky material was trimmed (see below).
## Contents
- **AZComputerGuru_StyleGuide.pdf** - the authoritative brand style guide. Start here.
- **Logos:** `logo-transwhite.png`, `logo-flatwhite.jpg`, `guru-vector.eps` (scalable vector master)
- **Guru Icons/** - favicon / app-icon sizes (16-512px)
- **Lato Font/** - full Lato family (TTF) + `OFL.txt` (SIL Open Font License) + `README.txt`
- **Colors.png** - brand color reference
- **social-avatar.jpg** - social profile avatar
- **acg-letterhead-2025.png** + **Letterhead 2025.docx** - current letterhead (image + editable source)
## Licensing
- The Lato font family is licensed under the SIL Open Font License - see `Lato Font/OFL.txt`.
## Curation note
Trimmed from the original archive as not forward-relevant for the website project:
legacy `Old/` marks (2016-2019 logos, 2019 letterhead), business cards (2015 + 2019),
raster flat-icon sheets, the superseded 2021 letterhead, and generic stock photography.
(The full original archive remains recoverable from git history if anything is needed later.)
The showcase site itself currently uses JetBrains Mono (see `../DESIGN.md`); the Lato
family here is ACG's corporate brand font for collateral (letterhead, cards, print).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,424 +0,0 @@
/* ===========================================================================
ARIZONA COMPUTER GURU — "Sonoran Ledger"
Hand-built. Warm paper, precise rules, mono numerals. No framework.
Baseline grid: 24px. Radius: 02px. Orange = ink, used sparingly.
=========================================================================== */
/* ---- Tokens ------------------------------------------------------------- */
:root {
--paper: #F7F3EB;
--surface: #EDE6D9;
--surface-2: #E4DACA;
--ink: #2A2521;
--ink-2: #5A5148;
--ink-3: #6D6456; /* AA-safe for small text on cream (~4.6:1) */
--rule: rgba(90, 81, 72, 0.16);
--rule-soft: rgba(90, 81, 72, 0.09);
--accent: #F2922E; /* the amber "ink" — fills, marks, underlines */
--accent-ink: #BD5A00; /* orange TEXT on light paper (AA-safe ~4.9:1) */
--on-accent: #2A2521; /* text sitting on an amber fill */
--good: #4F7A3F;
--maxw: 1140px;
--base: 24px; /* baseline unit */
--f-display: "Barlow Condensed", "Arial Narrow", system-ui, sans-serif;
--f-body: "Lexend", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
--f-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
--shadow: 0 1px 0 var(--rule), 0 18px 40px -28px rgba(40, 33, 25, 0.45);
}
[data-theme="dark"] {
--paper: #1C1814;
--surface: #2A2520;
--surface-2: #322B24;
--ink: #E8DFCE;
--ink-2: #C4B8A3;
--ink-3: #9A8C77;
--rule: rgba(196, 184, 163, 0.16);
--rule-soft: rgba(196, 184, 163, 0.08);
--accent: #F2A24E;
--accent-ink: #F4A85C; /* orange text on dark paper (AA-safe) */
--on-accent: #1C1814;
--good: #8FB97E;
--shadow: 0 1px 0 var(--rule), 0 22px 48px -30px rgba(0, 0, 0, 0.7);
}
/* ---- Reset -------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
* { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
body {
background: var(--paper);
color: var(--ink);
font-family: var(--f-body);
font-size: 1rem;
line-height: 1.5; /* 24px at 16px → on-grid */
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
transition: background 0.4s ease, color 0.4s ease;
}
img { display: block; max-width: 100%; height: auto; }
a { color: var(--accent-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--ink); }
::selection { background: var(--accent); color: var(--on-accent); }
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
/* ---- Layout primitives -------------------------------------------------- */
.wrap { width: min(100% - 3rem, var(--maxw)); margin-inline: auto; }
.wrap--narrow { width: min(100% - 3rem, 760px); margin-inline: auto; }
section { padding-block: calc(var(--base) * 3.5); }
.section-tag {
font-family: var(--f-mono);
font-size: 0.72rem;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--accent-ink);
display: flex; align-items: center; gap: 0.75rem;
margin-bottom: var(--base);
}
.section-tag::before { /* precision mark, not an icon font */
content: ""; width: 28px; height: 0;
border-top: 2px solid var(--accent);
}
.section-tag span { color: var(--ink-3); }
h1, h2, h3, h4 { font-family: var(--f-display); font-weight: 600; line-height: 1.04;
letter-spacing: -0.01em; color: var(--ink); }
h2 { font-size: clamp(2rem, 4.5vw, 3.25rem); margin-bottom: var(--base); }
h3 { font-size: 1.5rem; font-weight: 600; }
.lead { font-size: 1.18rem; color: var(--ink-2); max-width: 60ch; }
.muted { color: var(--ink-2); }
.mono { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }
/* underline "ink" used on key phrases */
.ul { background-image: linear-gradient(var(--accent), var(--accent));
background-size: 100% 2px; background-position: 0 92%; background-repeat: no-repeat;
padding-bottom: 1px; }
/* ---- Buttons ------------------------------------------------------------ */
.btn {
font-family: var(--f-display); font-weight: 600; font-size: 1.05rem;
letter-spacing: 0.01em;
display: inline-flex; align-items: center; gap: 0.6rem;
padding: 0.7rem 1.4rem; border: 1px solid transparent; border-radius: 2px;
cursor: pointer; text-decoration: none; transition: transform 0.15s ease, background 0.2s ease;
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover { color: var(--on-accent); filter: brightness(1.05); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn--ghost:hover { border-color: var(--accent); color: var(--ink); }
.btn .arrow { font-family: var(--f-mono); }
/* ---- Header ------------------------------------------------------------- */
.site-header {
position: sticky; top: 0; z-index: 50;
background: color-mix(in srgb, var(--paper) 86%, transparent);
backdrop-filter: blur(8px);
border-bottom: 1px solid var(--rule);
}
.site-header .wrap { display: flex; align-items: center; gap: 1.5rem;
min-height: calc(var(--base) * 3); }
.brand { display: flex; align-items: baseline; gap: 0.6rem; text-decoration: none; color: var(--ink); }
.brand__mark { /* CSS-drawn monogram, not an image icon */
font-family: var(--f-display); font-weight: 700; font-size: 1.05rem;
letter-spacing: 0.05em; color: var(--on-accent); background: var(--accent);
padding: 0.15rem 0.5rem; border-radius: 2px; align-self: center;
}
.brand__name { font-family: var(--f-display); font-weight: 600; font-size: 1.35rem;
letter-spacing: 0.005em; }
.brand__since { font-family: var(--f-mono); font-size: 0.66rem; letter-spacing: 0.18em;
text-transform: uppercase; color: var(--ink-3); }
.nav { margin-left: auto; display: flex; align-items: center; gap: 1.2rem; }
.nav__links { display: flex; align-items: center; gap: 1.6rem; }
.nav a { font-family: var(--f-body); font-size: 0.92rem; color: var(--ink-2);
text-decoration: none; }
.nav a:hover { color: var(--ink); }
.nav__phone { font-family: var(--f-mono); color: var(--ink) !important; font-weight: 500; }
.theme-toggle, .nav__toggle {
background: transparent; border: 1px solid var(--rule); border-radius: 2px;
width: 44px; height: 44px; cursor: pointer; color: var(--ink);
display: grid; place-items: center; font-size: 1.1rem; transition: border-color 0.2s;
}
.theme-toggle:hover, .nav__toggle:hover { border-color: var(--accent); }
.nav__toggle { display: none; font-family: var(--f-mono); line-height: 1; }
@media (max-width: 880px) {
.nav__toggle { display: grid; }
.nav__links {
position: absolute; top: 100%; left: 0; right: 0;
flex-direction: column; align-items: stretch; gap: 0;
background: var(--paper); border-bottom: 1px solid var(--rule);
box-shadow: var(--shadow); padding: 0.5rem 0;
max-height: 0; overflow: hidden; visibility: hidden;
transition: max-height 0.25s ease, visibility 0.25s ease;
}
.site-header.nav-open .nav__links { max-height: 60vh; visibility: visible; }
.nav__links a { padding: 0.85rem 1.5rem; font-size: 1.05rem;
border-top: 1px solid var(--rule-soft); }
}
/* ---- Hero --------------------------------------------------------------- */
.hero { padding-block: calc(var(--base) * 3) calc(var(--base) * 4); position: relative; }
.hero .wrap { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: calc(var(--base) * 2);
align-items: center; }
.hero__eyebrow { font-family: var(--f-mono); font-size: 0.78rem; letter-spacing: 0.2em;
text-transform: uppercase; color: var(--accent-ink); margin-bottom: var(--base); }
.hero h1 { font-size: clamp(2.6rem, 6vw, 4.6rem); font-weight: 700; }
.hero h1 .amp { color: var(--accent-ink); white-space: nowrap; }
.hero__sub { font-size: 1.3rem; color: var(--ink-2); margin-top: var(--base);
max-width: 38ch; }
.hero__cta { display: flex; gap: 1rem; margin-top: calc(var(--base) * 1.5); flex-wrap: wrap; }
.hero__note { font-family: var(--f-mono); font-size: 0.78rem; color: var(--ink-3);
margin-top: var(--base); }
.hero__frame {
border: 1px solid var(--rule); border-radius: 2px; overflow: hidden;
box-shadow: var(--shadow); background: var(--surface); position: relative;
}
.hero__frame img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.hero__caption {
font-family: var(--f-mono); font-size: 0.72rem; color: var(--ink-3);
padding: 0.6rem 0.9rem; border-top: 1px solid var(--rule);
display: flex; justify-content: space-between; background: var(--surface);
}
@media (max-width: 860px) {
.hero .wrap { grid-template-columns: 1fr; }
.hero__frame { order: -1; }
}
/* ---- Ledger ruling background (signature) ------------------------------- */
.ledger {
background-image: repeating-linear-gradient(
to bottom, transparent, transparent 23px, var(--rule-soft) 23px, var(--rule-soft) 24px);
background-position: 0 0;
}
/* ---- Trust strip -------------------------------------------------------- */
.trust { border-block: 1px solid var(--rule); background: var(--surface); }
.trust .wrap { display: grid; grid-template-columns: repeat(4, 1fr);
gap: 1px; background: var(--rule); }
.trust__cell { background: var(--surface); padding: calc(var(--base) * 1.25) 1.25rem; }
.trust__num { font-family: var(--f-mono); font-size: 1.9rem; font-weight: 600;
color: var(--ink); line-height: 1; }
.trust__num .u { color: var(--accent-ink); }
.trust__label { font-size: 0.86rem; color: var(--ink-2); margin-top: 0.5rem; }
@media (max-width: 720px) { .trust .wrap { grid-template-columns: repeat(2, 1fr); } }
/* ---- Concierge story ---------------------------------------------------- */
.story .wrap { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--base) * 2.2);
align-items: center; }
.story__img { border: 1px solid var(--rule); border-radius: 2px; overflow: hidden;
box-shadow: var(--shadow); }
.story__img img { aspect-ratio: 3 / 2; object-fit: cover; width: 100%; }
.story p + p { margin-top: var(--base); }
.story blockquote {
font-family: var(--f-display); font-weight: 500; font-size: 1.6rem; line-height: 1.15;
color: var(--ink); border-left: 2px solid var(--accent); padding-left: 1.1rem;
margin-top: calc(var(--base) * 1.2);
}
@media (max-width: 820px) {
.story .wrap { grid-template-columns: 1fr; }
.story__img { order: -1; }
}
/* ---- Services (continuous ledger list, not cards) ----------------------- */
.svc-list { border-top: 1px solid var(--rule); margin-top: var(--base); }
.svc {
display: grid; grid-template-columns: 2.4rem 1fr auto; gap: 1.25rem;
align-items: baseline; padding-block: calc(var(--base) * 0.9);
border-bottom: 1px solid var(--rule); transition: background 0.2s ease;
}
.svc:hover { background: var(--surface); }
.svc__no { font-family: var(--f-mono); font-size: 0.8rem; color: var(--ink-3); }
.svc__name { font-family: var(--f-display); font-size: 1.5rem; font-weight: 600; }
.svc__desc { color: var(--ink-2); font-size: 0.98rem; margin-top: 0.25rem; max-width: 60ch; }
.svc__meta { font-family: var(--f-mono); font-size: 0.82rem; color: var(--accent-ink);
text-align: right; white-space: nowrap; }
@media (max-width: 680px) {
.svc { grid-template-columns: 1.8rem 1fr; }
.svc__meta { grid-column: 2; text-align: left; }
}
/* ---- Pricing rate card -------------------------------------------------- */
.pricing { background: var(--surface); border-block: 1px solid var(--rule); }
.rate-card { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
background: var(--rule); border: 1px solid var(--rule); border-radius: 2px; overflow: hidden; }
.tier { background: var(--paper); padding: calc(var(--base) * 1.5) 1.5rem; position: relative;
align-self: stretch; }
.tier--pop { background: var(--surface-2); box-shadow: inset 0 3px 0 var(--accent); }
.tier__flag { position: absolute; top: 0; right: 0; font-family: var(--f-mono);
font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase;
background: var(--accent); color: var(--on-accent); padding: 0.25rem 0.6rem; }
.tier__name { font-family: var(--f-display); font-size: 1.7rem; font-weight: 600; }
.tier__price { font-family: var(--f-mono); font-size: 2.6rem; font-weight: 700;
color: var(--ink); margin-top: 0.5rem; line-height: 1; }
.tier__price .per { font-size: 0.9rem; color: var(--ink-3); font-weight: 400; }
.tier__blurb { color: var(--ink-2); font-size: 0.92rem; margin-top: 0.75rem;
padding-bottom: var(--base); border-bottom: 1px solid var(--rule); }
.tier ul { list-style: none; padding: 0; margin-top: var(--base); display: grid; gap: 0.5rem; }
.tier li { font-size: 0.92rem; color: var(--ink-2); padding-left: 1.4rem; position: relative; }
.tier li::before { content: "+"; position: absolute; left: 0; color: var(--accent-ink);
font-family: var(--f-mono); font-weight: 700; }
.tier li.is-base::before { content: "\2713"; }
@media (max-width: 820px) { .rate-card { grid-template-columns: 1fr; } }
.plans { margin-top: calc(var(--base) * 2); }
.plan-table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.plan-table caption { text-align: left; font-family: var(--f-mono); font-size: 0.74rem;
letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-3);
padding-bottom: 0.75rem; }
.plan-table th, .plan-table td { text-align: left; padding: 0.7rem 0.9rem;
border-bottom: 1px solid var(--rule); }
.plan-table thead th { font-family: var(--f-mono); font-size: 0.72rem; letter-spacing: 0.1em;
text-transform: uppercase; color: var(--ink-3); font-weight: 500; }
.plan-table td.num, .plan-table th.num { font-family: var(--f-mono); text-align: right;
font-variant-numeric: tabular-nums; }
.plan-table tr:hover td { background: var(--surface); }
.plan-table .pop td { color: var(--ink); }
.plan-table .pop td:first-child::after { content: " \25C6"; color: var(--accent-ink); }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.plan-table { min-width: 460px; }
/* visible keyboard focus everywhere interactive */
.btn:focus-visible, a:focus-visible, button:focus-visible, .faq__q:focus-visible,
.theme-toggle:focus-visible, .nav__toggle:focus-visible {
outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px;
}
/* ---- Calculator (centerpiece) ------------------------------------------ */
.calc { position: relative; }
.calc__shell {
border: 1px solid var(--rule); border-radius: 2px; box-shadow: var(--shadow);
background: var(--paper); overflow: hidden;
}
.calc__grid { display: grid; grid-template-columns: 1.15fr 0.85fr; }
.calc__inputs { padding: calc(var(--base) * 1.5); border-right: 1px solid var(--rule); }
.calc__row { display: grid; grid-template-columns: 1fr auto; align-items: center;
gap: 1rem; padding-block: calc(var(--base) * 0.6); border-bottom: 1px dashed var(--rule); }
.calc__row label { font-size: 0.98rem; color: var(--ink); }
.calc__row .hint { display: block; font-size: 0.78rem; color: var(--ink-3); margin-top: 0.15rem; }
.calc__control { display: flex; align-items: center; gap: 0.5rem; }
.stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--rule);
border-radius: 2px; overflow: hidden; }
.stepper button { width: 44px; min-height: 44px; border: 0; background: var(--surface);
color: var(--ink); font-family: var(--f-mono); font-size: 1.2rem; cursor: pointer; }
.stepper button:hover { background: var(--accent); color: var(--on-accent); }
.stepper input { width: 64px; height: 44px; border: 0; text-align: center; background: var(--paper);
color: var(--ink); font-family: var(--f-mono); font-size: 1.05rem; font-weight: 600;
appearance: textfield; -moz-appearance: textfield; }
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button {
-webkit-appearance: none; margin: 0; }
select, .calc__control select {
font-family: var(--f-body); font-size: 0.95rem; color: var(--ink);
background: var(--paper); border: 1px solid var(--rule); border-radius: 2px;
padding: 0.5rem 2rem 0.5rem 0.7rem; cursor: pointer;
appearance: none;
background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
background-position: calc(100% - 16px) 55%, calc(100% - 11px) 55%;
background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
select:focus, .stepper input:focus, input:focus { outline: 2px solid var(--accent);
outline-offset: 1px; }
.toggle-row { display: flex; align-items: center; gap: 0.6rem; }
.switch { position: relative; width: 44px; height: 24px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch .track { position: absolute; inset: 0; background: var(--surface-2);
border: 1px solid var(--rule); border-radius: 2px; transition: background 0.2s; }
.switch .knob { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
background: var(--ink-3); border-radius: 1px; transition: transform 0.2s, background 0.2s; }
.switch input:checked + .track { background: color-mix(in srgb, var(--accent) 35%, var(--surface)); }
.switch input:checked + .track + .knob, .switch input:checked ~ .knob { transform: translateX(20px);
background: var(--accent); }
/* ledger output side */
.calc__out { padding: calc(var(--base) * 1.5); background: var(--surface);
display: flex; flex-direction: column; }
.calc__out h3 { font-size: 1.15rem; }
.ledger-lines { margin-top: var(--base); flex: 1; }
.lline { display: grid; grid-template-columns: 1fr auto; align-items: baseline;
font-family: var(--f-mono); font-size: 0.9rem; padding-block: 0.45rem;
color: var(--ink-2); }
.lline .lcost { color: var(--ink); font-variant-numeric: tabular-nums; }
.lline.dots .lname { position: relative; }
.lline.is-zero { display: none; }
.calc__divider { border: 0; border-top: 1px solid var(--ink-3); margin-block: 0.75rem; }
.calc__total { display: grid; grid-template-columns: 1fr auto; align-items: end; }
.calc__total .tlabel { font-family: var(--f-display); font-size: 1.1rem; letter-spacing: 0.02em;
text-transform: uppercase; color: var(--ink-2); }
.calc__total .tnum { font-family: var(--f-mono); font-size: 2.9rem; font-weight: 700;
color: var(--ink); line-height: 1; }
.calc__annual { font-family: var(--f-mono); font-size: 0.82rem; color: var(--ink-3);
text-align: right; margin-top: 0.4rem; }
.calc__perep { font-family: var(--f-mono); font-size: 0.82rem; color: var(--accent-ink);
margin-top: 0.2rem; text-align: right; }
.calc__cta { margin-top: var(--base); }
.calc__foot { font-size: 0.78rem; color: var(--ink-3); margin-top: 1rem; }
@media (max-width: 820px) {
.calc__grid { grid-template-columns: 1fr; }
.calc__inputs { border-right: 0; border-bottom: 1px solid var(--rule); }
}
/* ---- FAQ ---------------------------------------------------------------- */
.faq { background: var(--surface); border-block: 1px solid var(--rule); }
.faq__item { border-bottom: 1px solid var(--rule); }
.faq__q { width: 100%; text-align: left; background: transparent; border: 0; cursor: pointer;
padding: calc(var(--base) * 0.9) 0; display: flex; justify-content: space-between;
gap: 1.5rem; align-items: center; color: var(--ink); font-family: var(--f-display);
font-size: 1.25rem; font-weight: 600; }
.faq__q .pm { font-family: var(--f-mono); color: var(--accent-ink); font-size: 1.4rem;
flex: none; transition: transform 0.2s; }
.faq__q[aria-expanded="true"] .pm { transform: rotate(45deg); }
.faq__a { overflow: hidden; max-height: 0; visibility: hidden;
transition: max-height 0.3s ease, visibility 0.3s ease; }
.faq__q[aria-expanded="true"] + .faq__a { visibility: visible; }
.faq__a-inner { padding-bottom: calc(var(--base) * 1.1); color: var(--ink-2); max-width: 70ch; }
/* ---- Contact ------------------------------------------------------------ */
.contact { padding-block: calc(var(--base) * 4.5); }
.contact .wrap { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--base) * 2.5);
align-items: start; }
.contact__lines { font-family: var(--f-mono); margin-top: var(--base); display: grid; gap: 0.6rem; }
.contact__lines .k { color: var(--ink-3); font-size: 0.72rem; letter-spacing: 0.14em;
text-transform: uppercase; }
.contact__lines .v { color: var(--ink); font-size: 1.05rem; }
.contact__lines a { color: var(--ink); }
.contact__lines a:hover { color: var(--accent-ink); }
.form-field { margin-bottom: var(--base); }
.form-field label { display: block; font-size: 0.85rem; color: var(--ink-2);
margin-bottom: 0.4rem; font-family: var(--f-mono); letter-spacing: 0.06em;
text-transform: uppercase; }
.form-field input, .form-field textarea {
width: 100%; font-family: var(--f-body); font-size: 1rem; color: var(--ink);
background: var(--paper); border: 1px solid var(--rule); border-radius: 2px;
padding: 0.65rem 0.8rem; }
.form-field textarea { min-height: calc(var(--base) * 4); resize: vertical; }
.form-note { font-size: 0.82rem; color: var(--ink-3); margin-top: 0.5rem; }
@media (max-width: 820px) { .contact .wrap { grid-template-columns: 1fr; } }
/* ---- Footer ------------------------------------------------------------- */
.site-footer { border-top: 1px solid var(--rule); padding-block: calc(var(--base) * 1.5);
background: var(--paper); }
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
align-items: center; }
.site-footer p { font-size: 0.84rem; color: var(--ink-3); font-family: var(--f-mono); }
.site-footer .disclaimer { width: 100%; font-size: 0.74rem; color: var(--ink-3);
border-top: 1px dashed var(--rule); padding-top: 0.9rem; margin-top: 0.5rem; }
/* reveal-on-scroll */
.reveal { opacity: 0; transform: translateY(12px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: none; }

View File

@@ -1 +0,0 @@
at-written.

View File

@@ -1,34 +0,0 @@
You are the LEAD design authority making the final call on art direction for a website. A second model (Grok) has proposed three directions as INPUT. Your job is to weigh them and decide.
PROJECT: Flagship single-page marketing website for "Arizona Computer Guru" (ACG), a Tucson MSP/IT-services company since 2001. Differentiator: "concierge IT" — go far beyond typical IT companies, genuine client relationships, transparent honest pricing, kind+direct (never condescending), local Tucson presence. Brand cues: warm amber-orange accent oklch(0.70 0.18 55), display font Barlow Condensed, body font Lexend.
HARD REQUIREMENTS: (1) must NOT look like generic AI-slop SaaS template; (2) genuinely beautiful + distinctive; (3) ALL text readable in BOTH light and dark themes (WCAG AA contrast, ~4.5:1 body); (4) interactive IT-cost calculator; (5) sections: hero, concierge story, services, GPS pricing tiers, trust/proof, FAQ, contact. Built as hand-crafted static HTML/CSS/vanilla-JS.
GROK'S THREE PROPOSED DIRECTIONS:
== 1. SONORAN LEDGER ==
Concept: page feels like a trusted local bookkeeper's ledger for the web — warm paper surfaces, precise horizontal rules, restrained type; pricing/calculator/story treated as permanent records, no marketing theater.
Light: bg cream #F7F3EB, surface #EDE6D9, text #2A2521, secondary #5A5148, orange accent only on active numbers/underlines/primary button. Dark: bg #1C1814, surface #2A2520, text #E8DFCE, secondary #C4B8A3, desaturated orange.
Type: Barlow Condensed 600-700 headlines + "Since 2001" lockup; Lexend body; JetBrains Mono for ALL prices/calculator output/endpoint counts (ledger precision).
Layout: contained hero, long single-column story with subtle rules, services as continuous text with orange underlines (not cards), pricing as a wide ruled rate card, calculator = the largest break (full-width "open ledger page" with live totals), quiet FAQ/contact.
Signature: faint continuous warm-gray ledger rulings (0.5-1px) behind story/pricing/calculator on a shared baseline grid so the whole scroll reads as one book.
== 2. DESERT THRESHOLD ==
Concept: site experienced as a sequence of architectural thresholds — moving from bright desert into shaded well-kept rooms; thick walls, deep reveals, Tucson 5pm light.
Light: bg plaster #F4F0E8, surface sand #E6DFD2, text #24201C, secondary #51463C, orange on door-like details + calculator action. Dark: bg umber #1A1612, surface #25211C, text #EDE3D3, secondary #B8A998.
Type: Barlow Condensed section titles + big "concierge" word; Lexend body; a quiet condensed geometric (Inter) for nav/buttons/calculator controls only.
Layout: tall framed hero, story = wide text column vs full-height "wall" image, services as a stepped vertical "hallway" list, pricing tiers as three recessed "openings in a thick wall" (not cards), calculator in its own deep niche, tighter FAQ/contact.
Signature: every section divider is a thick horizontal "beam/lintel" (CSS border+shadow) like moving under architecture; calculator has the deepest reveal, sits lower.
== 3. THE WORKBENCH ==
Concept: everything arranged on one long solid workbench; honest materials (wood, metal, paper, warm light); visitor sits across from the craftsman; no theater.
Light: bg warm gray #F1EDE5, surface wood #D9CDB8, text #2C2621, secondary #5C5146. Dark: bg #1D1914, surface #2E2720, text #E6D9C7, secondary #A99A85.
Type: Barlow Condensed headlines + pricing tier names only; Lexend everything else; no third face.
Layout: low wide hero "across the bench top", story two tight columns above a horizontal work-surface band, services as running inventory down left edge, pricing + calculator on widest "continuous bench surface" (tiers left, live calculator right), trust as small object photos.
Signature: pricing tiers + calculator rendered as physical objects resting on one continuous wooden plane with realistic soft shadows.
YOUR TASK:
1. For EACH direction: assess (a) how distinctive/anti-generic it truly is, (b) light+dark contrast/readability risk given the proposed palettes — call out ANY pairs that fail ~4.5:1 and give corrected hex, (c) build feasibility in static HTML/CSS, (d) the single biggest risk.
2. Make the CALL: which direction to build (you may recommend a refined hybrid). Justify against "concierge, premium, Tucson-local, anti-generic" and against readability in both themes.
3. Give the build 4-5 concrete, non-negotiable design rules to guarantee it's beautiful and NOT AI-slop.
Keep it tight and decisive, under ~650 words.

View File

@@ -1,45 +0,0 @@
[OK] VERDICT: Build a refined version of **SONORAN LEDGER**.
This direction captures the "Concierge" and "Since 2001" essence through the lens of precision, longevity, and transparency. It is the strongest antidote to SaaS-slop because it trades "shiny tech" for "trusted record."
---
### 1. DIRECTION ASSESSMENT
**== 1. SONORAN LEDGER ==**
* **(a) Distinctiveness:** Very High. It reframes IT as a meticulous craft rather than an abstract cloud service. It feels established and high-end.
* **(b) Contrast Risk:** Light Theme: Orange accent `oklch(0.70 0.18 55)` (~#FF8D2E) on Cream `#F7F3EB` is ~2.3:1. **[ERROR]** This fails for text. *Correction:* Darken orange to `#BD5A00` for text links/active numbers. Dark Theme: Orange on `#1C1814` is ~6.2:1 (Pass).
* **(c) Build Feasibility:** Extreme. CSS Grid + `repeating-linear-gradient` for ledger lines.
* **(d) Biggest Risk:** Looking like a dry accounting firm. Needs high-quality typography and motion to feel "alive."
**== 2. DESERT THRESHOLD ==**
* **(a) Distinctiveness:** Medium. Atmospheric but risks feeling like an architecture portfolio.
* **(b) Contrast Risk:** Solid. Secondary `#51463C` on `#F4F0E8` is ~6.3:1 (Pass).
* **(c) Build Feasibility:** Moderate. Requires careful box-shadow management to maintain "depth" without performance lag.
* **(d) Biggest Risk:** Heavy "beams" and "walls" might make the content feel cramped on mobile.
**== 3. THE WORKBENCH ==**
* **(a) Distinctiveness:** High, but dangerously nostalgic.
* **(b) Contrast Risk:** Solid. Secondary `#5C5146` on `#F1EDE5` is ~5.7:1 (Pass).
* **(c) Build Feasibility:** Low. Success depends entirely on the quality of "wood" assets/textures. If they look like stock photos, the brand dies.
* **(d) Biggest Risk:** Falling into the "2012 Skeuomorphism" trap. Hard to execute without looking dated.
---
### 2. THE CALL: SONORAN LEDGER (REFINED)
I am choosing **SONORAN LEDGER** with a hybrid infusion of **DESERT THRESHOLDs** depth.
**Justification:** ACG is a concierge service. A ledger represents the "Permanent Record" of a 25-year relationship. It communicates that every endpoint and every dollar is accounted for. It is the ultimate expression of "transparent, honest pricing." By using JetBrains Mono for data and Lexend for the story, we create a "High-End Workshop" feel that is professional yet approachable.
---
### 3. NON-NEGOTIABLE DESIGN RULES (ANTI-SLOP)
1. **THE INK RULE:** The orange accent is treated as "highlighting ink." Use it ONLY for active data points, underlines, and the primary CTA. Never use it for large background blocks or generic icons.
2. **ZERO GENERIC ICONOGRAPHY:** Do not use FontAwesome or Heroicons. If a section needs an icon, use a CSS-drawn geometric shape, a simplified technical schematic, or a high-resolution photo of actual hardware. AI-slop relies on "Friendly 3D People" and "Outline Icons"; we use "Precision Marks."
3. **THE LEDGER GRID:** Every element on the page must snap to a strict 24px vertical baseline grid. The "faint rulings" are not just decoration; they must align perfectly with the `line-height` of the Lexend body text.
4. **DATA AS DESIGN:** The IT-cost calculator is the centerpiece. Do not hide it in a "Get a Quote" pop-up. Treat the calculator's output with the same typographic dignity as the Hero headline. Large, mono-spaced numbers that feel "stamped" onto the page.
5. **NO OVER-SMOOTHED RADIUS:** Standard SaaS uses 12px-16px border-radius. We use 0px (sharp) or a maximum of 2px. Sharp corners communicate "Precise" and "Manual."
[INFO] This direction provides the highest "Trust-per-Pixel" for a local MSP. Proceed with static build.

View File

@@ -1,22 +0,0 @@
#!/usr/bin/env bash
# Generate Sonoran Ledger imagery with Grok. Photographic, anti-AI-slop, warm Tucson palette.
set -u
ROOT=/d/ClaudeTools
GROK="$ROOT/.claude/skills/grok/scripts/ask-grok.sh"
OUT="$ROOT/projects/acg-website-showcase/assets/images"
cd "$ROOT"
echo "=== [1/4] hero ==="
bash "$GROK" image "Photorealistic editorial photograph, late afternoon golden hour. A warm light-wood desk in a calm Tucson office. On the desk: an open paper accounting ledger with neat handwritten columns of numbers, a modern matte-aluminum laptop with no logos open beside it, a plain white ceramic coffee cup, and a brass fountain pen. Behind the desk a large window frames the distant Santa Catalina mountains and a single saguaro cactus in warm hazy desert light. Natural raking side light, soft long shadows, subtle fine film grain, gentle shallow depth of field. No people. Calm, premium, trustworthy mood. Warm cream, tan and soft amber tones, restrained and not orange-saturated. Wide 3:2 landscape composition." "$OUT/hero.png"
echo "=== [2/4] story windowsill ==="
bash "$GROK" image "Photorealistic architectural close-up. Warm desert golden-hour light rakes across the corner where a smooth hand-troweled white stucco wall meets a clean light-wood windowsill. Minimal, calm, textural, quiet shadow play. Tucson afternoon light, soft fine film grain, warm cream and tan palette. No text, no people, no logos. Wide 3:2 landscape." "$OUT/story.png"
echo "=== [3/4] trust still life ==="
bash "$GROK" image "Photorealistic editorial still life on a warm wooden desk in soft afternoon window light. In focus: an open paper notebook with a date neatly hand-written in ink, and a well-worn keyboard. In the soft out-of-focus background, a small potted barrel cactus sits on a windowsill. Honest, lived-in, premium and human. Warm cream and charcoal palette, fine film grain. No logos, no visible faces. Wide 3:2 landscape." "$OUT/trust.png"
echo "=== [4/4] paper texture ==="
bash "$GROK" image "Seamless subtle warm cream paper texture, very faint fibers and tone variation, almost flat, high resolution, soft and clean, suitable as a quiet website background. No text, no objects, evenly lit. Square." "$OUT/paper.png"
echo "=== DONE ==="
ls -la "$OUT"

View File

@@ -1,24 +0,0 @@
Design-direction consultation (text only, no image generation). You are an opinionated senior art director.
CONTEXT: Art-directing a flagship single-page marketing website for "Arizona Computer Guru" (ACG), a Tucson MSP / IT-services company operating since 2001. Core differentiator: "concierge IT" — they go far beyond typical IT companies, build genuine relationships with clients, transparent honest pricing, kind + direct (never condescending), strong local Tucson presence. Brand voice from their own materials: anti-sales-games, transparent, premium-but-grounded, "we built it the way we'd want to be treated."
Existing brand cues to respect (but you may evolve): accent orange ~oklch(0.70 0.18 55) (a warm amber-orange), display font Barlow Condensed, body font Lexend.
HARD REQUIREMENTS:
- Must NOT look like a generic AI-slop SaaS template (no default gradient-blob hero, no purple, no generic 3-card row clichés).
- Must be genuinely beautiful, distinctive, memorable.
- ALL text readable in BOTH a light theme and a dark theme.
- Includes an interactive IT-cost calculator.
- Sections to convey: hero, concierge story/differentiator, services, GPS pricing tiers ($19/$26/$39 per endpoint + support plans), trust/proof, FAQ, contact.
DELIVERABLE: Give me 3 DISTINCT, concrete, BUILDABLE art directions. For each include:
1. Name
2. Core visual concept (one tight paragraph)
3. Color strategy — explicit for LIGHT theme and DARK theme (name the background, surface, text, accent roles)
4. Typography approach (how Barlow Condensed + Lexend are used; any third face)
5. Layout / section rhythm (how the long scroll is paced)
6. Imagery treatment — exactly what hero image + 2-3 section images Grok should generate (describe each image so I can prompt it)
7. ONE signature distinctive element that makes it memorable
8. What specifically keeps it from looking generic
Then RANK the 3 by which best expresses "concierge, premium, Tucson-local, anti-generic" and say why in 2 sentences. Be specific and opinionated. Keep under ~750 words total.

View File

@@ -1,54 +0,0 @@
**Sonoran Ledger**
Core visual concept: The page feels like a trusted local bookkeepers ledger updated for the web — precise horizontal rules, warm paper surfaces, and restrained typography carrying every number and promise with the same weight as the desert light. No marketing theater; the design treats pricing, the calculator, and the story as permanent records.
Color strategy — LIGHT: Background warm cream #F7F3EB; surface soft paper #EDE6D9; primary text deep warm charcoal #2A2521; secondary #5A5148; accent remains the specified oklch(0.70 0.18 55) orange used only for active numbers, underlines, and the single “Get the estimate” button. DARK: Background warm deep charcoal #1C1814; surface muted slate-brown #2A2520; primary text warm parchment #E8DFCE; secondary #C4B8A3; accent orange desaturated slightly for contrast on dark.
Typography approach: Barlow Condensed 600700 for every headline, subhead, and the “Since 2001” lockup with tight tracking and generous line height. Lexend for all body, story, and form labels at comfortable reading sizes. JetBrains Mono (or system mono) used exclusively for every price, the calculator output, and endpoint counts — this single-face restriction gives the whole page its ledger precision.
Layout / section rhythm: Hero (contained, not full-bleed), then a long single-column “page” for the concierge story broken only by subtle rules. Services read as continuous justified text with occasional orange accent underlines instead of cards. Pricing sits as a wide ruled rate card. The calculator becomes the largest break in rhythm — a full-width interactive panel treated as an open ledger page with live totals. Trust and FAQ stay quiet and narrow; contact closes with one clear phone/email block.
Imagery treatment: Hero — late-afternoon Tucson interior, wooden desk with an open paper ledger showing neat columns, a modern but unbranded laptop, a white coffee cup, and a window framing distant Catalina mountains and one saguaro; natural side light, slight film grain, no people. Section image 1 (concierge story) — close crop of a stucco wall meeting a clean wooden windowsill with desert light raking across it. Section image 2 (trust) — horizontal strip of three quiet details: a hand writing a date in a notebook, a well-worn keyboard on a desk, a small potted barrel cactus on a windowsill.
Signature distinctive element: Extremely faint warm-gray ledger rulings (0.51 px) that run continuously behind the story, pricing, and calculator, aligned to a consistent baseline grid so the entire scroll reads as one continuous book.
What specifically keeps it from looking generic: The entire information architecture is subordinated to the ledger metaphor; there are no floating cards, no gradient blobs, no three-up grids, and the calculator is not an afterthought widget but the central “open page.”
**Desert Threshold**
Core visual concept: The site is experienced as a sequence of thresholds — moving from the bright desert into shaded, well-kept rooms where real work and real conversations happen. Architecture, not abstraction: thick walls, deep reveals, and light that feels like Tucson at 5 p.m.
Color strategy — LIGHT: Background off-white plaster #F4F0E8; surface warmer sand #E6DFD2; primary text near-black #24201C; secondary #51463C; accent orange used for door-like details and the calculators primary action. DARK: Background deep warm umber #1A1612; surface #25211C; primary text soft warm #EDE3D3; secondary #B8A998; accent orange kept but never glowing.
Typography approach: Barlow Condensed for all section titles and the large “concierge” word in the story. Lexend for body and most UI. A quiet, slightly condensed geometric (Inter or similar) for navigation, buttons, and calculator controls only — keeps the display face special.
Layout / section rhythm: Short, tall hero with a literal framed view. Concierge story uses a wide left text column against a right full-height “wall” image. Services use a stepped vertical list that feels like walking down a hallway. Pricing tiers are presented as three equal “openings” in a thick wall (subtle recessed panels, not cards). The calculator sits in its own deep niche after pricing. Trust, FAQ, and contact fold back into tighter, lower-ceiling passages.
Imagery treatment: Hero — exterior of a simple Tucson adobe or stucco building at golden hour, shot straight-on through a deep shaded portal or window frame so the viewer is literally looking “in”; one clean saguaro and mountain ridge visible beyond; no people. Section image 1 — interior corner where white plaster meets thick wooden lintel and a slice of bright desert is visible through an open door. Section image 2 — tight shot of a real wooden threshold with a worn doormat, a pair of clean work boots, and a small brass house number plate.
Signature distinctive element: Every major section divider is a thick horizontal “beam” or lintel (CSS border + shadow) that creates the sensation of moving under architectural elements; the calculator panel has the deepest reveal and sits lower, like stepping down into the workroom.
What specifically keeps it from looking generic: The visual system is built from real Tucson residential and small commercial architecture rather than UI patterns; the pacing feels like walking through a cared-for building, not scrolling a marketing deck.
**The Workbench**
Core visual concept: Everything is arranged on a single long, solid workbench. Materials are honest (wood, metal, paper, warm light). The visitor sits across from the craftsman; pricing, the calculator, and proof are all laid out at working height with no theater.
Color strategy — LIGHT: Background soft warm gray #F1EDE5; primary surface #D9CDB8 (actual wood tone); text #2C2621; secondary #5C5146; accent orange only on active elements and the calculator total. DARK: Background #1D1914; surface #2E2720; text #E6D9C7; secondary #A99A85; accent orange held at the same hue but lowered lightness for legibility.
Typography approach: Barlow Condensed for headlines and the pricing tier names only. Lexend for everything else. No third face — the two fonts plus the physical surface treatment carry all distinction.
Layout / section rhythm: Hero is low and wide, like looking across the bench top. The concierge story is two tight columns of text above a long horizontal “work surface” band. Services are listed as a single running inventory down the left edge. Pricing and the calculator occupy the widest, most physical-feeling section — a continuous bench surface that holds the three tiers on the left and the live calculator on the right. Trust uses small object photos set directly into the surface. FAQ and contact sit at the far end of the bench.
Imagery treatment: Hero — straight-down or 3/4 view of a real wooden workbench in a Tucson garage or workshop; on the bench: a clean laptop, a paper work order, a tape measure, a small orange-handled tool, and a cup; strong side light from a window, visible concrete or stucco wall behind. Section image 1 — macro of hands (one older, one younger) plugging a clean network cable into a small switch on the same bench. Section image 2 — close detail of the bench edge with a few honest scuffs, a brass ruler, and a printed invoice showing the $19 / $26 / $39 numbers.
Signature distinctive element: The pricing tiers and calculator are rendered as objects actually resting on the same continuous wooden plane; subtle material texture, soft realistic shadows, and a consistent “edge” treatment make the interactive elements feel physical rather than overlaid.
What specifically keeps it from looking generic: The metaphor is resolutely physical and local (a real bench in a real Tucson workshop) instead of any digital “surface”; the calculator is not a module but part of the same working surface as the prices.
**Ranking**
1. Sonoran Ledger (best)
2. Desert Threshold
3. The Workbench
Sonoran Ledger best expresses concierge, premium, Tucson-local, and anti-generic because the entire visual language is built around transparent record-keeping rather than marketing decoration — the calculator and pricing literally sit inside the “books,” which directly embodies the client promise of honest numbers and no games. The other two are still strong and local, but Threshold risks feeling more like a boutique hotel and Workbench slightly more tradesman than the relationship-first concierge positioning.

View File

@@ -1,29 +0,0 @@
### index.html
[ERROR] Accessibility: FAQ accordion buttons lack `aria-controls` and panels lack `id`s (line 217). Verified by checking markup. Confidence: 100%.
[WARN] Accessibility: Calculator `aria-live="polite"` (line 197) contains the entire output ledger. Refutation attempt: Maybe `app.js` debounces input? No, `app.js:125` fires `recalc()` and rewrites DOM immediately on every `input` event, causing severe screen reader spam while typing. Confidence: 100%.
[OK] Form labels (line 261): Explicitly linked via `for`/`id`.
[OK] Focus visibility: Custom outlines exist for inputs, and default browser outlines remain intact for buttons since no global reset exists. Confidence: 100%.
### styles.css
[ERROR] WCAG Contrast (Light): `--ink-3` (`#837868`) on `--paper` (`#F7F3EB`) yields ~3.8:1, failing AA 4.5:1. Refutation attempt: Is it only used for large text? No, it's used for small body text like `.hero__note` and `.calc__foot`. Corrected hex: `#6D6456`. Confidence: 100%.
[ERROR] Accessibility: Collapsed FAQ answers `.faq__a` (line 327) hide visually via `max-height: 0` but lack `visibility: hidden`. Screen readers will inappropriately read collapsed answers. Confidence: 100%.
[ERROR] Responsive: Mobile nav links are `display: none` < 880px (line 127). Refutation attempt: Because it is a single-page site, users can still scroll. However, removing primary wayfinding without a hamburger fallback completely breaks standard user expectation. Confidence: High.
[WARN] Responsive: Pricing tables lack a horizontal overflow wrapper. A 5-column table will break 320px mobile viewports. Confidence: 100%.
[OK] WCAG Contrast (Dark): `--ink-3` (`#9A8C77`) on `#1C1814` is 5.3:1. Both light/dark `--accent-ink` and button texts pass AA comfortably. Confidence: 100%.
### app.js
[WARN] Calculator Edge Case: Typing an empty string `""` evaluates safely to `0` mathematically (line 64). Refutation attempt: Does this break the math? No. Does it break UI state? Yes, `input.value` is not overwritten in the UI during typing, leaving the input visually blank while the calculator computes `0`. Confidence: 100%.
[OK] Calculator Math: Divide-by-zero is handled safely via `endpoints > 0` condition (line 112). `NaN` correctly defaults to `0`. Confidence: 100%.
[OK] Theme Toggle: Properly sets `aria-pressed` and respects system preferences dynamically (line 16). Confidence: 100%.
### Design & Art Direction
[OK] AI-slop: None detected. The "Sonoran Ledger" constraints (strict 24px baseline, tabular-nums, sparse orange accent) are mathematically and visually respected. Copy is direct and avoids generic SaaS bloat words.
### PRIORITIZED FIX LIST
1. **[CRITICAL]** Update `--ink-3` in `styles.css:12` to `#6D6456` to meet WCAG AA contrast.
2. **[CRITICAL]** Add `visibility: hidden` to `.faq__a` (`styles.css:327`) and `visibility: visible` to its expanded state to prevent screen reader leakage.
3. **[HIGH]** Implement a mobile menu fallback for viewports `< 880px` rather than purely hiding `.nav__link` (`styles.css:127`).
4. **[HIGH]** Wrap `.plan-table` in an `overflow-x: auto` container to prevent layout breakage on narrow screens (`index.html:120`).
5. **[MED]** Add `id`s to FAQ panels and `aria-controls` to FAQ buttons (`index.html:217`).
6. **[MED]** Scope `aria-live` to specific total spans or debounce the `input` listener to prevent screen reader spam (`index.html:197`, `app.js:125`).
7. **[LOW]** Add a `blur` listener to calculator inputs to visually sync empty/invalid inputs back to `"0"` (`app.js:61`).

View File

@@ -1,62 +0,0 @@
**VERDICT**
Hand-built static site that largely executes the "Sonoran Ledger" direction (warm paper #F7F3EB/#1C1814, sparse --accent orange as ink only, mono tabular numerals for money, 2px sharp corners, repeating-linear-gradient ledger rulings at 24px baseline). It is not generic AI-slop in the visual layer — custom tokens, no framework, hand-rolled selects/switches/steppers, sectional rulings, split trust numerals, and explicit "open book" copy differentiate it. However, the information architecture (hero/trust/story/services/pricing/calc/faq/contact/footer) is the standard MSP marketing skeleton, and several real defects exist, especially in JS behavior and mobile.
Prioritized by the requested hunt areas. All analysis from the three full file reads. No modifications performed.
**index.html**
[ERROR] Mobile navigation breakage. At <=880px, `.nav .nav__link` are hidden via CSS with no hamburger, no remaining in-nav anchors, and no alternative (e.g., footer or select). Only the phone number and theme toggle survive in the header. Sections #services, #pricing, #calculator, #faq become unreachable without scrolling the entire page on phones/tablets. (cross-ref css/styles.css:154)
[ERROR] "Send me this estimate" (id="sendEstimate") is a plain `<a href="#contact">`. It performs scroll only; calculator state (ledger lines, total) is never injected into #cf-msg or any hidden field. The contact form and estimator are completely disconnected. (index.html:362)
[WARN] Schema.org LocalBusiness "image" and the two `<img>` src values point to "assets/images/hero.png" / "assets/images/story.png" (relative, no root guarantee). If served from a subpath the images 404 and JSON-LD is invalid. Width/height present on imgs (good). (index.html:20,82,124)
[WARN] Accordion (FAQ) buttons carry aria-expanded correctly, but the answer containers lack role="region", id, or aria-labelledby wiring back to the button. Content remains in DOM (good for search), but grouping is weak for assistive tech. (index.html:377-407)
[INFO] Semantics otherwise strong: `<main>`, skip link, section+aria-labelledby, table+caption+scope="col", label+for on all form controls (including the custom switch and number inputs), tel/mailto, descriptive alts on the two photos, novalidate + custom validation on contact. Trust strip uses a labeled section + grid of cells (not a list or dl, but acceptable). Inline style tweaks exist on a few containers for spacing (minor hygiene).
[INFO] No obvious duplicate IDs, broken heading order, or missing lang/color-scheme. The `<span id="top">` inside main is harmless but odd.
**css/styles.css**
[INFO] Tokens and dark override correctly implement the spec: --paper/--surface warm, --rule/--rule-soft for lines, --accent/#BD5A00 (light) and #F2A24E/#F4A85C (dark) used only for marks, flags, underlines (.ul), section-tag::before rules, brand mark, hover states, and selection. No heavy rounded corners (2px max), no large blurs except header. .mono + font-variant-numeric: tabular-nums on all money. Ledger ruling via precise repeating-linear-gradient (23px transparent + 1px at 24px) on .ledger sections only. (css/styles.css:9-46,184-189,254, etc.)
[WARN] Contrast. Tokens comment claims AA for --accent-ink. Core --ink on --paper is high-contrast. --ink-2 muted (#5A5148 light / #C4B8A3 dark) on body copy and small labels is borderline, especially at 0.78-0.92rem. Rule lines (rgba 0.16 / 0.08) and ledger rulings are intentionally faint; in dark mode or outdoors they become nearly invisible. This undercuts the "premium ledger" readability claim on real devices. (css/styles.css:13,38,101,186)
[WARN] Mobile risks beyond nav. Stepper buttons fixed at 34px wide (sub-44px touch minimum). Many breakpoints (880/860/820/720/680) but no container queries; tables and grids can squeeze (right-aligned .num columns in plan-table). Header sticky + backdrop-filter is modern but the surviving mobile nav content (phone + 40px toggle) can feel cramped. No focus-visible beyond the form-control outline rule. (css/styles.css:154,288-292,264-269,346-349,382)
[INFO] Distinctive execution, not templated. Custom chevron-less selects (bg-image linear gradients), custom .switch, custom .stepper (spinners explicitly killed), grid-gap + background-rule trick for trust separators, reveal using IntersectionObserver, section tags with accent rule, .tier--pop flag, .svc continuous ruled list instead of cards. The visual system fights generic. However, the overall page skeleton, "Most chosen" ribbon, trust strip, live two-pane estimator, and +/x FAQ are still recognizable marketing patterns.
[OK] Reduced-motion, box-sizing, and basic reset present. Body transitions limited to bg/color.
**js/app.js**
[ERROR] Stepper bounds + direct edit desync (core bug). Stepper click path (js/app.js:139) does `Math.max(0, Math.min(500, v + dir))` and writes back. But `intVal` (67-72) only clamps the *read* value for calculations (`if (v > 500) v = 500; return v;`) and never mutates `el.value`. Typing 600 (or -5) into an endpoints/m365/voip field leaves the input showing the out-of-range number while every recalc, line, total, and per-endpoint uses the clamped 500/0. Subsequent stepper clicks read the lying input.value. (js/app.js:67-72,136-143)
[ERROR] Calculator "per endpoint" math/presentation. `per = endpoints > 0 ? total / endpoints : 0` (125) then unconditionally renders "X per endpoint / mo". Total includes large fixed adders (support plan 200-850, equip 25, m365, voip, hosting). The displayed per-endpoint figure therefore amortizes the support plan etc. across seats. This contradicts the page claim "the same math we'd walk you through in person" and "per-endpoint pricing". Arithmetic is correct; the semantics of the output are misleading when any non-endpoint item is selected. (js/app.js:119,125-128)
[WARN] Support-plan line exactly as flagged. `var support = numSelect("support");` (94) pulls the raw `<option value="380">` price. It is passed verbatim as the `cost` argument to `lineRow` (114): `lineRow((supportName || "Support plan") + " support", ..., support)`. The same raw value is added directly into total (119). For the "None" case (value 0) this produces the label "Support plan support" (supportName falls to "") with cost 0 (hidden by .is-zero). Functionally the total is correct (flat fee), but it is the only line that does not compute cost from a rate; it trusts the select value as both identifier and dollar amount. (js/app.js:94,105-107,114,119)
[WARN] FAQ max-height on resize is present but fragile. Click handler (159) sets `panel.style.maxHeight = (inner.offsetHeight + 8) + "px"`. Resize listener (163-171) re-queries every open panel and does the same. Issues: magic +8, only updates *currently open* panels, measures at event time (font loading, subpixel, zoom, or post-open reflow can still clip or leave extra space), no removal of style on close beyond hard "0px", no MutationObserver for content changes. Works for static text on this page but is a classic source of cut-off answers. (js/app.js:152-171)
[INFO] Theme persistence. STORE="acg-theme", localStorage read on load, write on toggle, OS prefers listener that only applies when no explicit saved value (40-48). Logic is correct. Weaknesses: initial `<html data-theme="light">` + script at very end of body guarantees a flash of the wrong theme on first paint for users with dark saved or OS dark. No early inline script or critical CSS. (js/app.js:12-49)
[INFO] Contact validation (demo level). Trims name + cf-contact only (181). No format check on the "phone or email" field. On error sets accent color + message + focus. On success sets good color + thanks + reset(). Note text/color survives the reset until next submit. No aria-live on #formNote (calc side has aria-live="polite" on the output shell). Correct for a static demo; insufficient for production. (js/app.js:173-192)
[OK] Remaining calculator paths: money() rounds, no NaN escapes in the hot path, form submit prevented, input+change both trigger recalc, steppers call recalc after write. Ledger hides zero lines. No other arithmetic defects found.
**Short ranked list of the top fixes that matter (real defects only, highest impact first)**
1. Mobile nav: .nav__link {display:none} at 880px with no menu or persistent anchors — primary navigation is lost on phones.
2. Stepper direct-edit desync: intVal clamps for math only; input.value can show values outside 0-500 while all outputs use the clamped number.
3. Per-endpoint display math: total (with fixed support/equip/etc.) is divided by endpoints and labeled "per endpoint / mo" — misrepresents the per-endpoint claim.
4. FAQ max-height: offsetHeight + 8 px snapshots on resize only for open items; content can clip after reflow, font load, or width change.
5. Theme flash + late application: hardcoded light on <html>, script at bottom; dark users see wrong theme before JS runs.
6. Touch targets: stepper +/- buttons locked at 34px wide.
7. Estimate-to-contact handoff missing: the CTA only scrolls; no data transfer occurs.
8. Support line label: raw price passed as cost produces "Support plan support" (value 0 case) and couples the select value to both identity and dollars.
9. Contact status region has no aria-live; results are invisible to screen readers.
10. Faint ledger rulings + muted text contrast: especially in dark mode; undercuts premium paper/ink readability.
The rest are nits (inline styles, brittle asset paths in JSON-LD, missing focus-visible on .btn, etc.). The site is closer to a deliberate craft artifact than a generic template, but the defects above are functional or accessibility issues that affect real use.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

View File

@@ -1,481 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Arizona Computer Guru — Concierge IT for Tucson, since 2001</title>
<meta name="description" content="Arizona Computer Guru is Tucson's concierge IT and managed security partner since 2001. Transparent per-endpoint pricing, local people, month-to-month terms. Estimate your IT cost in seconds." />
<meta name="color-scheme" content="light dark" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@500;600;700&family=Lexend:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/styles.css" />
<!-- Set theme before first paint to avoid a flash of the wrong theme. -->
<script>
(function () {
try {
var s = localStorage.getItem("acg-theme");
var m = s || (window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
document.documentElement.setAttribute("data-theme", m);
} catch (e) {}
})();
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Arizona Computer Guru",
"image": "assets/images/hero.png",
"description": "Concierge managed IT and cybersecurity for Tucson businesses since 2001.",
"address": {
"@type": "PostalAddress",
"streetAddress": "7437 E. 22nd St",
"addressLocality": "Tucson",
"addressRegion": "AZ",
"postalCode": "85710",
"addressCountry": "US"
},
"telephone": "+1-520-304-8300",
"url": "https://azcomputerguru.com",
"foundingDate": "2001",
"areaServed": "Tucson, Arizona",
"openingHours": "Mo-Fr 09:00-17:00"
}
</script>
</head>
<body>
<a href="#main" class="sr-only">Skip to content</a>
<!-- ======================= HEADER ======================= -->
<header class="site-header">
<div class="wrap">
<a class="brand" href="#top" aria-label="Arizona Computer Guru home">
<span class="brand__mark" aria-hidden="true">ACG</span>
<span>
<span class="brand__name">Arizona Computer Guru</span><br />
<span class="brand__since">Concierge IT &middot; Tucson &middot; since 2001</span>
</span>
</a>
<nav class="nav" aria-label="Primary">
<div class="nav__links" id="navLinks">
<a class="nav__link" href="#services">Services</a>
<a class="nav__link" href="#pricing">Pricing</a>
<a class="nav__link" href="#calculator">Estimate</a>
<a class="nav__link" href="#faq">FAQ</a>
</div>
<a class="nav__phone" href="tel:+15203048300">520.304.8300</a>
<button class="theme-toggle" id="themeToggle" type="button"
aria-pressed="false" aria-label="Switch to dark theme" title="Toggle light / dark">
<span aria-hidden="true" data-theme-icon>&#9728;</span>
</button>
<button class="nav__toggle" id="navToggle" type="button"
aria-expanded="false" aria-controls="navLinks" aria-label="Open menu">&#8801;</button>
</nav>
</div>
</header>
<main id="main">
<span id="top"></span>
<!-- ======================= HERO ======================= -->
<section class="hero ledger" aria-labelledby="hero-h">
<div class="wrap">
<div class="hero__copy reveal">
<p class="hero__eyebrow">Tucson &middot; Managed IT &amp; Security &middot; Est. 2001</p>
<h1 id="hero-h">Concierge IT for Tucson&mdash;<br />every number <span class="amp">on the table.</span></h1>
<p class="hero__sub">We go further than your last IT company, build a real relationship, and never hide the math&mdash;honest pricing, local people, problems fixed before you feel them.</p>
<div class="hero__cta">
<a class="btn btn--primary" href="#calculator">Estimate your cost <span class="arrow" aria-hidden="true">&rarr;</span></a>
<a class="btn btn--ghost" href="#contact">Talk to a human</a>
</div>
<p class="hero__note mono">// Month-to-month &middot; no lock-in &middot; no offshore call centers</p>
</div>
<figure class="hero__frame reveal">
<img src="assets/images/hero.png" width="1248" height="832"
alt="A wooden desk at golden hour with an open paper ledger, a laptop, and a coffee cup; the Santa Catalina mountains and a saguaro visible through the window." />
<figcaption class="hero__caption">
<span>Tucson, AZ</span><span>open book, nothing hidden</span>
</figcaption>
</figure>
</div>
</section>
<!-- ======================= TRUST STRIP ======================= -->
<section class="trust" aria-label="Why businesses stay with us" style="padding-block:0;">
<div class="wrap">
<div class="trust__cell">
<div class="trust__num">20<span class="u">01</span></div>
<div class="trust__label">Serving Tucson businesses since</div>
</div>
<div class="trust__cell">
<div class="trust__num">1&ndash;2<span class="u">hr</span></div>
<div class="trust__label">Typical onsite emergency response</div>
</div>
<div class="trust__cell">
<div class="trust__num">100<span class="u">%</span></div>
<div class="trust__label">Local team &mdash; never offshore</div>
</div>
<div class="trust__cell">
<div class="trust__num">30<span class="u">day</span></div>
<div class="trust__label">Cancel anytime, no penalty</div>
</div>
</div>
</section>
<!-- ======================= CONCIERGE STORY ======================= -->
<section class="story" id="concierge" aria-labelledby="story-h">
<div class="wrap">
<div class="story__copy reveal">
<p class="section-tag">Our difference <span>/ concierge</span></p>
<h2 id="story-h">What "concierge" actually means</h2>
<p class="muted">Most IT companies wait for things to break, route you to a call center three time zones away, and lock you into a three-year contract. We built Arizona Computer Guru to be the opposite of that.</p>
<p class="muted">Concierge means we learn your business, not just your network. We pick up the phone. We translate in plain English instead of talking down to you. We&rsquo;ll drive across town when it&rsquo;s faster than a remote session. And because we charge the same whether your systems break or not, our incentive is simple: <span class="ul">keep them running</span>.</p>
<blockquote>We built our service the way we&rsquo;d want to be treated if we were the customer.</blockquote>
</div>
<figure class="story__img reveal">
<img src="assets/images/story.png" width="1248" height="832"
alt="Warm afternoon desert light raking across a white stucco wall meeting a clean wooden windowsill." />
</figure>
</div>
</section>
<!-- ======================= SERVICES ======================= -->
<section class="services ledger" id="services" aria-labelledby="svc-h">
<div class="wrap">
<p class="section-tag">Everything you need <span>/ one local partner</span></p>
<h2 id="svc-h">Services, laid out plainly</h2>
<div class="svc-list">
<article class="svc reveal">
<div class="svc__no">01</div>
<div><div class="svc__name">Managed IT (GPS)</div><p class="svc__desc">24/7 monitoring, automated patching, and a help desk that knows your name. Guru Protection Services keeps your endpoints healthy and accounted for.</p></div>
<div class="svc__meta">from&nbsp;$19&nbsp;/endpoint</div>
</article>
<article class="svc reveal">
<div class="svc__no">02</div>
<div><div class="svc__name">Cybersecurity</div><p class="svc__desc">Advanced EDR, email security, dark-web monitoring, and security-awareness training that catch what plain antivirus misses.</p></div>
<div class="svc__meta">in GPS-Pro &amp; up</div>
</article>
<article class="svc reveal">
<div class="svc__no">03</div>
<div><div class="svc__name">Backup &amp; Recovery</div><p class="svc__desc">Tested backups, offsite copies, and ransomware rollback&mdash;so a bad day is an inconvenience, not a closure.</p></div>
<div class="svc__meta">in GPS-Pro &amp; up</div>
</article>
<article class="svc reveal">
<div class="svc__no">04</div>
<div><div class="svc__name">Microsoft 365 &amp; Email</div><p class="svc__desc">Migrations, Business Standard/Premium, or budget-friendly hosted email&mdash;configured, secured, and supported.</p></div>
<div class="svc__meta">from&nbsp;$2&nbsp;/mailbox</div>
</article>
<article class="svc reveal">
<div class="svc__no">05</div>
<div><div class="svc__name">Business Phones (GPS-Voice)</div><p class="svc__desc">Cloud phone systems with mobile and desktop apps, auto-attendants, and porting. Four tiers, no usage surprises.</p></div>
<div class="svc__meta">from&nbsp;$22&nbsp;/user</div>
</article>
<article class="svc reveal">
<div class="svc__no">06</div>
<div><div class="svc__name">Web &amp; Email Hosting</div><p class="svc__desc">Managed hosting with free SSL, daily backups, and real humans&mdash;not a ticket robot&mdash;when something needs a hand.</p></div>
<div class="svc__meta">from&nbsp;$15&nbsp;/mo</div>
</article>
<article class="svc reveal">
<div class="svc__no">07</div>
<div><div class="svc__name">Projects &amp; Block Time</div><p class="svc__desc">Migrations, network buildouts, and one-off work&mdash;billed against pre-paid hours that never expire.</p></div>
<div class="svc__meta">from&nbsp;$100&nbsp;/hr</div>
</article>
<article class="svc reveal">
<div class="svc__no">08</div>
<div><div class="svc__name">vCIO &amp; Compliance</div><p class="svc__desc">Strategy, budgeting, and cyber-insurance readiness. We help you check the boxes auditors and insurers ask for.</p></div>
<div class="svc__meta">in GPS-Advanced</div>
</article>
</div>
</div>
</section>
<!-- ======================= PRICING ======================= -->
<section class="pricing" id="pricing" aria-labelledby="price-h">
<div class="wrap">
<p class="section-tag">Published, not "call for quote" <span>/ per endpoint</span></p>
<h2 id="price-h">GPS monitoring &amp; protection</h2>
<p class="lead">You pay for exactly the computers you have&mdash;no rounding you up into a bigger package tier.</p>
<div class="rate-card" role="list" style="margin-top:var(--base);">
<div class="tier" role="listitem">
<div class="tier__name">GPS-Basic</div>
<div class="tier__price">$19 <span class="per">/ endpoint / mo</span></div>
<p class="tier__blurb">Essential monitoring for small, simple environments.</p>
<ul>
<li class="is-base">Remote monitoring &amp; management</li>
<li class="is-base">Automated patch management</li>
<li class="is-base">Business-grade antivirus</li>
<li class="is-base">8&times;5 help desk</li>
<li class="is-base">Monthly health reports</li>
</ul>
</div>
<div class="tier tier--pop" role="listitem">
<div class="tier__flag">Most chosen</div>
<div class="tier__name">GPS-Pro</div>
<div class="tier__price">$26 <span class="per">/ endpoint / mo</span></div>
<p class="tier__blurb">Comprehensive protection for growing businesses.</p>
<ul>
<li class="is-base">Everything in Basic</li>
<li>24&times;7 help desk</li>
<li>Advanced EDR &amp; email security</li>
<li>Dark-web monitoring</li>
<li>Backup &amp; disaster recovery</li>
<li>Security-awareness training</li>
</ul>
</div>
<div class="tier" role="listitem">
<div class="tier__name">GPS-Advanced</div>
<div class="tier__price">$39 <span class="per">/ endpoint / mo</span></div>
<p class="tier__blurb">Enterprise-grade security &amp; compliance.</p>
<ul>
<li class="is-base">Everything in Pro</li>
<li>Compliance management (HIPAA/SOC)</li>
<li>Ransomware rollback</li>
<li>Virtual CIO services</li>
<li>Priority response SLA</li>
<li>Dedicated account manager</li>
</ul>
</div>
</div>
<p class="muted" style="margin-top:1rem;font-size:0.9rem;">Add equipment monitoring (routers, switches, printers, NAS) for <span class="mono">$25/mo</span> up to 10 devices.</p>
<div class="plans">
<div class="table-wrap">
<table class="plan-table">
<caption>Support plans &mdash; bundled labor at a lower effective rate</caption>
<thead>
<tr><th scope="col">Plan</th><th class="num" scope="col">Monthly</th><th class="num" scope="col">Hours</th><th class="num" scope="col">Effective&nbsp;rate</th><th scope="col">Response</th></tr>
</thead>
<tbody>
<tr><td>Essential</td><td class="num">$200</td><td class="num">2</td><td class="num">$100/hr</td><td>Next business day</td></tr>
<tr class="pop"><td>Standard</td><td class="num">$380</td><td class="num">4</td><td class="num">$95/hr</td><td>8 hours</td></tr>
<tr><td>Premium</td><td class="num">$540</td><td class="num">6</td><td class="num">$90/hr</td><td>4 hours</td></tr>
<tr><td>Priority</td><td class="num">$850</td><td class="num">10</td><td class="num">$85/hr</td><td>2 hours, 24/7</td></tr>
</tbody>
</table>
</div>
<div class="table-wrap">
<table class="plan-table" style="margin-top:var(--base);">
<caption>Block time &mdash; pre-paid hours that never expire</caption>
<thead>
<tr><th scope="col">Block</th><th class="num" scope="col">Price</th><th class="num" scope="col">Effective&nbsp;rate</th><th scope="col">Notes</th></tr>
</thead>
<tbody>
<tr><td>10 hours</td><td class="num">$1,500</td><td class="num">$150/hr</td><td>Use anytime, no expiry</td></tr>
<tr><td>20 hours</td><td class="num">$2,600</td><td class="num">$130/hr</td><td>Bank &amp; draw down</td></tr>
<tr><td>30 hours</td><td class="num">$3,000</td><td class="num">$100/hr</td><td>Best per-hour value</td></tr>
</tbody>
</table>
</div>
<p class="muted" style="margin-top:1rem;font-size:0.9rem;">Off-plan labor is <span class="mono">$175/hr</span>. Plans and block time bring that down&mdash;and there&rsquo;s never a charge to find out what something will cost.</p>
</div>
</div>
</section>
<!-- ======================= CALCULATOR ======================= -->
<section class="calc ledger" id="calculator" aria-labelledby="calc-h">
<div class="wrap">
<p class="section-tag">No email wall, no sales call <span>/ live estimate</span></p>
<h2 id="calc-h">Your IT, accounted for</h2>
<p class="lead">Move the numbers. Watch the total. This is the same math we&rsquo;d walk you through in person&mdash;nothing hidden behind a &ldquo;contact sales&rdquo; button.</p>
<div class="calc__shell" style="margin-top:var(--base);">
<div class="calc__grid">
<!-- INPUTS -->
<form class="calc__inputs" id="calcForm" aria-label="IT cost estimator">
<div class="calc__row">
<label for="endpoints">Computers &amp; servers <span class="hint">Every monitored endpoint</span></label>
<div class="calc__control">
<div class="stepper" data-step="endpoints">
<button type="button" data-dir="-1" aria-label="Fewer endpoints">&minus;</button>
<input id="endpoints" name="endpoints" type="number" inputmode="numeric" min="0" max="500" value="22" />
<button type="button" data-dir="1" aria-label="More endpoints">+</button>
</div>
</div>
</div>
<div class="calc__row">
<label for="gpsTier">Protection tier <span class="hint">Per-endpoint monitoring level</span></label>
<div class="calc__control">
<select id="gpsTier" name="gpsTier">
<option value="19">GPS-Basic &mdash; $19</option>
<option value="26" selected>GPS-Pro &mdash; $26</option>
<option value="39">GPS-Advanced &mdash; $39</option>
</select>
</div>
</div>
<div class="calc__row">
<label for="equip">Equipment monitoring <span class="hint">Network gear, printers, NAS &mdash; $25/mo</span></label>
<div class="calc__control toggle-row">
<span class="switch">
<input type="checkbox" id="equip" name="equip" />
<span class="track" aria-hidden="true"></span><span class="knob" aria-hidden="true"></span>
</span>
</div>
</div>
<div class="calc__row">
<label for="support">Support plan <span class="hint">Bundled labor hours each month</span></label>
<div class="calc__control">
<select id="support" name="support">
<option value="0">None &mdash; pay as you go</option>
<option value="200">Essential &mdash; $200 (2 hr)</option>
<option value="380" selected>Standard &mdash; $380 (4 hr)</option>
<option value="540">Premium &mdash; $540 (6 hr)</option>
<option value="850">Priority &mdash; $850 (10 hr)</option>
</select>
</div>
</div>
<div class="calc__row">
<label for="m365">Microsoft 365 users <span class="hint">Business Standard, $14/user</span></label>
<div class="calc__control">
<div class="stepper" data-step="m365">
<button type="button" data-dir="-1" aria-label="Fewer Microsoft 365 users">&minus;</button>
<input id="m365" name="m365" type="number" inputmode="numeric" min="0" max="500" value="0" />
<button type="button" data-dir="1" aria-label="More Microsoft 365 users">+</button>
</div>
</div>
</div>
<div class="calc__row">
<label for="voip">Business phone users <span class="hint">GPS-Voice Standard, $28/user</span></label>
<div class="calc__control">
<div class="stepper" data-step="voip">
<button type="button" data-dir="-1" aria-label="Fewer phone users">&minus;</button>
<input id="voip" name="voip" type="number" inputmode="numeric" min="0" max="500" value="0" />
<button type="button" data-dir="1" aria-label="More phone users">+</button>
</div>
</div>
</div>
<div class="calc__row" style="border-bottom:0;">
<label for="hosting">Web hosting <span class="hint">Managed, with SSL &amp; backups</span></label>
<div class="calc__control">
<select id="hosting" name="hosting">
<option value="0" selected>None</option>
<option value="15">Starter &mdash; $15</option>
<option value="35">Business &mdash; $35</option>
<option value="65">Commerce &mdash; $65</option>
</select>
</div>
</div>
</form>
<!-- OUTPUT (ledger page) -->
<div class="calc__out">
<h3>Monthly statement</h3>
<div class="ledger-lines" id="ledgerLines"><!-- JS fills --></div>
<hr class="calc__divider" />
<div class="calc__total" aria-live="polite">
<span class="tlabel">Per month</span>
<span class="tnum mono" id="totalMonthly">$0</span>
</div>
<div class="calc__annual mono" id="totalAnnual">$0 / year</div>
<div class="calc__perep mono" id="perEndpoint">&mdash; all-in, per endpoint / mo</div>
<a class="btn btn--primary calc__cta" href="#contact" id="sendEstimate">Send me this estimate <span class="arrow" aria-hidden="true">&rarr;</span></a>
<p class="calc__foot">Estimate only &mdash; your real quote is tailored to your setup. No card, no commitment, and we&rsquo;ll tell you if you&rsquo;re buying more than you need.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ======================= FAQ ======================= -->
<section class="faq" id="faq" aria-labelledby="faq-h">
<div class="wrap wrap--narrow">
<p class="section-tag">Straight answers <span>/ ask us anything</span></p>
<h2 id="faq-h">Questions worth asking any MSP</h2>
<div class="faq__list" id="faqList">
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>Will I get a real person, or an offshore call center?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">A real, local person. Our team works out of our Tucson office at 7437 E. 22nd St. You can visit, and after hours you reach an on-call tech who is also local&mdash;not a queue overseas.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>What&rsquo;s your contract term?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">Month-to-month. Cancel with 30 days&rsquo; notice, no early-termination fee. We&rsquo;d rather earn your business every month than trap you in a three-year agreement.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>What happens if I use more support hours than my plan includes?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">Plan hours are used first. After that we draw from any pre-paid block time you&rsquo;ve banked ($100&ndash;150/hr), which never expires. No block time? Overage is billed at $175/hr&mdash;and we&rsquo;ll always flag it before the meter runs.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>How fast do you respond to an emergency?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">By plan: Standard is 8 hours, Premium 4 hours, Priority 2 hours around the clock. A total outage is escalated immediately regardless of plan, and for local clients we&rsquo;re typically onsite within 1&ndash;2 hours.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>What security is actually included?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">GPS-Pro and above include advanced EDR, email security, dark-web monitoring, and monthly security-awareness training. GPS-Advanced adds compliance tooling and ransomware rollback. Basic antivirus alone isn&rsquo;t enough anymore, so we don&rsquo;t pretend it is.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>Can you help me meet cyber-insurance requirements?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">Yes. GPS-Pro covers most of what insurers ask for&mdash;MFA enforcement, EDR, training, and cloud backups&mdash;and we&rsquo;ll provide documentation for your agent. We work with several Tucson insurance agents regularly.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>What if my team grows or shrinks?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">Billing is per endpoint, so it just follows your headcount. Add three people, add three endpoints; downsize and it drops the next month. No contract amendments, no penalties.</div></div>
</div>
<div class="faq__item">
<button class="faq__q" aria-expanded="false"><span>Do you really publish your pricing?</span><span class="pm" aria-hidden="true">+</span></button>
<div class="faq__a"><div class="faq__a-inner">You&rsquo;re looking at it. Our rates are on this page and in our Buyers Guide. We think hiding prices is a red flag&mdash;in any MSP, including us.</div></div>
</div>
</div>
</div>
</section>
<!-- ======================= CONTACT ======================= -->
<section class="contact ledger" id="contact" aria-labelledby="contact-h">
<div class="wrap">
<div class="contact__intro reveal">
<p class="section-tag">No pressure, no pitch <span>/ let&rsquo;s talk</span></p>
<h2 id="contact-h">Talk to a human</h2>
<p class="muted">Tell us what&rsquo;s frustrating you, or send over an estimate from the calculator. We&rsquo;ll give you honest feedback&mdash;even if that&rsquo;s &ldquo;your current setup is fine, here&rsquo;s one thing to fix.&rdquo;</p>
<div class="contact__lines">
<div><span class="k">Phone</span><br /><a class="v" href="tel:+15203048300">520.304.8300</a></div>
<div><span class="k">Email</span><br /><a class="v" href="mailto:info@azcomputerguru.com">info@azcomputerguru.com</a></div>
<div><span class="k">Office</span><br /><span class="v">7437 E. 22nd St, Tucson, AZ 85710</span></div>
<div><span class="k">Hours</span><br /><span class="v">Mon&ndash;Fri 9&ndash;5 &middot; 24/7 emergency for Priority clients</span></div>
</div>
</div>
<form class="contact__form reveal" id="contactForm" novalidate>
<div class="form-field">
<label for="cf-name">Your name</label>
<input id="cf-name" name="name" type="text" autocomplete="name" required />
</div>
<div class="form-field">
<label for="cf-biz">Business</label>
<input id="cf-biz" name="business" type="text" autocomplete="organization" />
</div>
<div class="form-field">
<label for="cf-contact">Phone or email</label>
<input id="cf-contact" name="contact" type="text" autocomplete="email" required />
</div>
<div class="form-field">
<label for="cf-msg">What can we help with?</label>
<textarea id="cf-msg" name="message"></textarea>
</div>
<button class="btn btn--primary" type="submit">Send message <span class="arrow" aria-hidden="true">&rarr;</span></button>
<p class="form-note" id="formNote" aria-live="polite">We reply the same business day. (Demo build &mdash; this form is not wired to a mailbox.)</p>
</form>
</div>
</section>
</main>
<!-- ======================= FOOTER ======================= -->
<footer class="site-footer">
<div class="wrap">
<p>&copy; <span id="year">2026</span> Arizona Computer Guru &middot; Protecting Tucson businesses since 2001</p>
<p><a href="tel:+15203048300">520.304.8300</a> &middot; <a href="mailto:info@azcomputerguru.com">info@azcomputerguru.com</a></p>
<p class="disclaimer">Local demonstration build of a proposed azcomputerguru.com. Pricing shown reflects published GPS rates and is illustrative for the estimator; a real quote is tailored to your environment. Photography is representational.</p>
</div>
</footer>
<script src="js/app.js"></script>
</body>
</html>

View File

@@ -1,261 +0,0 @@
/* ===========================================================================
Arizona Computer Guru — Sonoran Ledger
Vanilla JS. Theme, calculator, FAQ, steppers, reveal. No dependencies.
=========================================================================== */
(function () {
"use strict";
var $ = function (s, c) { return (c || document).querySelector(s); };
var $$ = function (s, c) { return Array.prototype.slice.call((c || document).querySelectorAll(s)); };
/* ---- Theme ------------------------------------------------------------ */
var root = document.documentElement;
var toggle = $("#themeToggle");
var icon = $("[data-theme-icon]");
var STORE = "acg-theme";
function applyTheme(mode) {
root.setAttribute("data-theme", mode);
var dark = mode === "dark";
if (toggle) {
toggle.setAttribute("aria-pressed", String(dark));
toggle.setAttribute("aria-label", dark ? "Switch to light theme" : "Switch to dark theme");
}
if (icon) icon.innerHTML = dark ? "&#9790;" : "&#9728;"; // moon / sun
}
var saved = null;
try { saved = localStorage.getItem(STORE); } catch (e) {}
var prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
applyTheme(saved || (prefersDark ? "dark" : "light"));
if (toggle) {
toggle.addEventListener("click", function () {
var next = root.getAttribute("data-theme") === "dark" ? "light" : "dark";
applyTheme(next);
try { localStorage.setItem(STORE, next); } catch (e) {}
});
}
// Follow the OS only while the user hasn't explicitly chosen.
if (window.matchMedia) {
var mq = window.matchMedia("(prefers-color-scheme: dark)");
var onChange = function (e) {
var explicit = null;
try { explicit = localStorage.getItem(STORE); } catch (err) {}
if (!explicit) applyTheme(e.matches ? "dark" : "light");
};
if (mq.addEventListener) mq.addEventListener("change", onChange);
else if (mq.addListener) mq.addListener(onChange);
}
/* ---- Dynamic year ----------------------------------------------------- */
var yr = $("#year");
if (yr) yr.textContent = String(new Date().getFullYear());
/* ---- Mobile nav ------------------------------------------------------- */
var header = $(".site-header");
var navToggle = $("#navToggle");
if (navToggle && header) {
var closeNav = function () {
header.classList.remove("nav-open");
navToggle.setAttribute("aria-expanded", "false");
navToggle.setAttribute("aria-label", "Open menu");
};
navToggle.addEventListener("click", function () {
var open = header.classList.toggle("nav-open");
navToggle.setAttribute("aria-expanded", String(open));
navToggle.setAttribute("aria-label", open ? "Close menu" : "Open menu");
});
$$("#navLinks a").forEach(function (a) { a.addEventListener("click", closeNav); });
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") closeNav();
});
}
/* ---- Money helper ----------------------------------------------------- */
function money(n) {
return "$" + Math.round(n).toLocaleString("en-US");
}
/* ---- Calculator ------------------------------------------------------- */
var form = $("#calcForm");
if (form) {
var EQUIP = 25;
var M365_RATE = 14; // Business Standard
var VOIP_RATE = 28; // GPS-Voice Standard
function intVal(id) {
var el = $("#" + id);
var v = parseInt(el && el.value, 10);
if (isNaN(v) || v < 0) v = 0;
if (v > 500) v = 500;
return v;
}
function numSelect(id) {
var el = $("#" + id);
var v = parseFloat(el && el.value);
return isNaN(v) ? 0 : v;
}
function lineRow(name, detail, cost) {
var zero = cost <= 0 ? " is-zero" : "";
return (
'<div class="lline' + zero + '">' +
'<span class="lname">' + name + (detail ? ' <span class="muted">' + detail + "</span>" : "") + "</span>" +
'<span class="lcost">' + money(cost) + "</span>" +
"</div>"
);
}
function recalc() {
var endpoints = intVal("endpoints");
var tier = numSelect("gpsTier");
var equip = $("#equip").checked;
var support = numSelect("support");
var m365 = intVal("m365");
var voip = intVal("voip");
var hosting = numSelect("hosting");
var gpsCost = endpoints * tier;
var equipCost = equip ? EQUIP : 0;
var m365Cost = m365 * M365_RATE;
var voipCost = voip * VOIP_RATE;
var tierName = tier === 19 ? "GPS-Basic" : tier === 39 ? "GPS-Advanced" : "GPS-Pro";
var supportName = support === 0 ? "" :
support === 200 ? "Essential" : support === 380 ? "Standard" :
support === 540 ? "Premium" : "Priority";
var hostingName = hosting === 0 ? "" :
hosting === 15 ? "Starter" : hosting === 35 ? "Business" : "Commerce";
var lines = "";
lines += lineRow(tierName + " monitoring", endpoints + " &times; " + money(tier), gpsCost);
lines += lineRow("Equipment monitoring", "up to 10 devices", equipCost);
lines += lineRow((supportName || "Support plan") + " support", supportName ? "bundled labor" : "none", support);
lines += lineRow("Microsoft 365", m365 + " &times; " + money(M365_RATE), m365Cost);
lines += lineRow("Business phones", voip + " &times; " + money(VOIP_RATE), voipCost);
lines += lineRow((hostingName || "Web hosting") + " hosting", hostingName ? "managed" : "none", hosting);
var total = gpsCost + equipCost + support + m365Cost + voipCost + hosting;
$("#ledgerLines").innerHTML = lines;
$("#totalMonthly").textContent = money(total);
$("#totalAnnual").textContent = money(total * 12) + " / year";
var per = endpoints > 0 ? total / endpoints : 0;
$("#perEndpoint").innerHTML = endpoints > 0
? money(per) + " all-in, per endpoint / mo"
: "&mdash; add endpoints to see per-seat cost";
}
function clampInt(v) {
if (isNaN(v) || v < 0) return 0;
return v > 500 ? 500 : v;
}
// Steppers
$$(".stepper").forEach(function (st) {
var input = $("input", st);
$$("button", st).forEach(function (b) {
b.addEventListener("click", function () {
var dir = parseInt(b.getAttribute("data-dir"), 10);
input.value = clampInt(parseInt(input.value, 10) + dir);
recalc();
});
});
// On commit (blur / Enter), snap a typed value back into range so the
// field never shows a number the math has silently clamped.
input.addEventListener("change", function () {
input.value = clampInt(parseInt(input.value, 10));
});
});
// Hand the built estimate to the contact form when "Send me this estimate"
// is clicked (the anchor still scrolls to #contact).
var sendBtn = $("#sendEstimate");
if (sendBtn) {
sendBtn.addEventListener("click", function () {
var msg = $("#cf-msg");
if (!msg) return;
var lines = $$("#ledgerLines .lline")
.filter(function (l) { return !l.classList.contains("is-zero"); })
.map(function (l) {
var name = $(".lname", l).textContent.replace(/\s+/g, " ").trim();
return "- " + name + ": " + $(".lcost", l).textContent.trim();
});
msg.value = "Here is the estimate I built:\n" + lines.join("\n") +
"\n\nMonthly: " + $("#totalMonthly").textContent +
" (" + $("#totalAnnual").textContent + ")\n\nI'd like to talk it through.";
});
}
form.addEventListener("input", recalc);
form.addEventListener("change", recalc);
form.addEventListener("submit", function (e) { e.preventDefault(); });
recalc();
}
/* ---- FAQ accordion ---------------------------------------------------- */
$$(".faq__q").forEach(function (q, i) {
var panel = q.nextElementSibling;
var inner = panel ? panel.firstElementChild : null;
// Wire ARIA relationships (button <-> answer region).
if (panel) {
var pid = "faq-a-" + (i + 1);
var qid = "faq-q-" + (i + 1);
panel.id = pid; q.id = qid;
panel.setAttribute("role", "region");
panel.setAttribute("aria-labelledby", qid);
q.setAttribute("aria-controls", pid);
}
q.addEventListener("click", function () {
var open = q.getAttribute("aria-expanded") === "true";
q.setAttribute("aria-expanded", String(!open));
if (panel) panel.style.maxHeight = open ? "0px" : (inner.scrollHeight + 8) + "px";
});
});
// Recompute open panel heights on resize (text reflow)
window.addEventListener("resize", function () {
$$(".faq__q").forEach(function (q) {
if (q.getAttribute("aria-expanded") === "true") {
var panel = q.nextElementSibling;
var inner = panel ? panel.firstElementChild : null;
if (panel && inner) panel.style.maxHeight = (inner.scrollHeight + 8) + "px";
}
});
});
/* ---- Contact form (demo) --------------------------------------------- */
var contact = $("#contactForm");
if (contact) {
contact.addEventListener("submit", function (e) {
e.preventDefault();
var name = $("#cf-name");
var contactField = $("#cf-contact");
var note = $("#formNote");
if (!name.value.trim() || !contactField.value.trim()) {
note.textContent = "Please add your name and a phone or email so we can reach you.";
note.style.color = "var(--accent-ink)";
(name.value.trim() ? contactField : name).focus();
return;
}
note.textContent = "Thanks, " + name.value.trim().split(" ")[0] +
" — in a live build this reaches our Tucson team. (Demo: nothing was sent.)";
note.style.color = "var(--good)";
contact.reset();
});
}
/* ---- Reveal on scroll ------------------------------------------------- */
var reveals = $$(".reveal");
if ("IntersectionObserver" in window && reveals.length) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (en) {
if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); }
});
}, { rootMargin: "0px 0px -8% 0px", threshold: 0.08 });
reveals.forEach(function (el) { io.observe(el); });
} else {
reveals.forEach(function (el) { el.classList.add("in"); });
}
})();

View File

@@ -1,60 +0,0 @@
# DESIGN.md — "Bold" (default)
The locked design language for the ACG site. Premium brutalist: confident authority
without arrogance. Anton poster headlines, signal orange accents, grayscale documentary
photos, refined 1px borders. Direct, transparent, inked precision.
## Color strategy: High-contrast refined brutalist
Sharp contrasts, near-neutral palette with signal orange as the ONLY accent color.
- **Light:** bone `#F4EDE1`, surface `#FBF7F0`, surface-2 `#EAE2D4`,
ink `#16120F`, ink-2 `#46403A`, ink-3 `#5C544B` (AA on bone ~5:1).
- **Dark:** near-black `#0C0A09`, surface `#16120F`, surface-2 `#1E1814`,
ink `#F4EDE1`, ink-2 `#C9C1B5`, ink-3 `#9A9082`.
- **Accent:** signal orange `#E24A12` (light) / `#FF5A1F` (dark) — fills, CTA,
underlines, marks. Orange TEXT: `#C23A0A` (light, AA) / `#FF8A4D` (dark, AA).
- Accent is restrained, authoritative. Never decorative gradients or tints.
## Theme
Both light and dark are first-class. Light = crisp professional confidence. Dark =
refined premium authority. System preference honored, set before first paint (no FOUC).
## Typography
- Display: **Anton** 400 (headlines, tier names, brand lockup, pricing numerals).
Uppercase for h1/h2/tier names. Sentence-case for functional labels (service names,
FAQ questions) to avoid condensed-caps smear at UI sizes.
- Body: **Hanken Grotesk** 400/500/700 (paragraphs, UI labels, functional copy).
- Mono: **JetBrains Mono** tabular-nums for money, calculator, endpoint counts.
- Hierarchy via size + case + weight. Large poster numerals lean into Anton's authority.
## Layout & rhythm
- 24px baseline. NO ledger rulings (dropped from the paper aesthetic).
- Hard 1px ink borders on major sections, header, rate cards, calculator shell.
- Vary spacing per page. Premium softening: extra breathing room on tiers/calc panels.
- Radius: 2px on buttons/cards/inputs (refined, not zero-radius industrial).
- Rate cards use ink background with 1px gap dividers (frame + inner grid unified).
## Photography
Grayscale documentary photos (scoped to .hero__frame / .story__img / .page-head--img /
.office-figure only). `filter: grayscale(1) contrast(1.08)` matches the high-contrast
palette. Future logos/badges/UI images stay color.
## Motion
- Reveal on scroll (opacity + small translate), ease-out only, respects reduced-motion.
- Never animate layout properties.
## Alternate skins (header switcher)
- **Midnight Concierge** — cool dark-premium slate aesthetic
- **Verdigris Gate** — oxidized-copper green/plaster, Fraunces serif, cool color photos
## House laws (impeccable)
- **No em dashes** anywhere in copy. Use commas, colons, semicolons, periods, parentheses.
- **No side-stripe accent borders** (no border-left/right > 1px as a colored accent).
Use full borders, leading numerals/marks, background tints, or nothing.
- No gradient text, no decorative glassmorphism, no hero-metric template, no AI slop.
## Multipage specifics
- Shared sticky header (brand + nav + theme toggle + skin switcher + mobile menu) and footer on every page.
- Active nav state per page (`aria-current="page"`).
- Pages: Home, Services, Pricing, Calculator, About, Contact. Each has its own
opening rhythm so the set never feels templated.

View File

@@ -1,44 +0,0 @@
# PRODUCT.md — Arizona Computer Guru (ACG) website
register: brand
## Product purpose
A multipage marketing website for Arizona Computer Guru, a Tucson managed-IT and
cybersecurity provider operating since 2001. The site sells trust before it sells
services: the goal is for a small-business owner to feel they have found honest,
local people who will go further than the last IT company, then to reach out or
build an estimate. Design IS the product here.
## Users
- Tucson / southern-Arizona small-business owners and office managers (roughly
5 to 100 employees): law firms, medical practices, accounting, construction,
property management, retail, manufacturing.
- Often burned before: surprise bills, offshore call centers, three-year lock-ins,
"unlimited support" that wasn't. Skeptical, value-conscious, not deeply technical.
- They want a real person, fast local help, and to know what it costs before a call.
## Brand & tone
- The differentiator is **concierge IT**: genuine relationships, going much further
than typical IT companies, at reasonable prices.
- Voice: kind, direct, transparent, plain-spoken, confident without arrogance.
Never condescending, never sales-pressure, never hype. "We built it the way we'd
want to be treated." Publishes its prices on purpose.
- Local and rooted: Tucson since 2001, physical office at 7437 E. 22nd St, onsite
in 1 to 2 hours, month-to-month terms.
## Anti-references (do NOT look like these)
- Generic SaaS/MSP slop: blue/purple gradients, floating 3D isometrics, server-rack
clip art, glowing shields, "hero metric" stat templates, identical icon-card grids.
- Hard-sell landing pages: countdown timers, fake scarcity, manufactured testimonials.
- Cold enterprise-security navy-and-gold. Cold healthcare white-and-teal.
## Strategic principles
- Transparency is the aesthetic. Show real numbers, real pricing, real process.
- Warmth and place: Tucson light, paper, ledgers, honest materials. Photographic,
not illustrated.
- Every word earns its place. No restated headings, no filler.
## Integrity rules
- No fabricated named client testimonials. Proof is built from verifiable facts.
- The contact form is a demo (not wired to a mailbox). Pricing is illustrative of
published GPS rates. Photography is representational.

View File

@@ -1,145 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>About | Arizona Computer Guru</title>
<meta name="description" content="A Tucson IT company since 2001. We started as a break-fix shop, then built GPS to align our incentives with our clients. Concierge IT, the way we'd want to be treated." />
<meta name="color-scheme" content="light dark" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@500;600;700&family=Lexend:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500;600;700&family=Fraunces:wght@400;500;600;700&family=Source+Sans+3:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600;700&family=Anton&family=Hanken+Grotesk:wght@400;500;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="icon" href="assets/logo/acg-mark.svg" type="image/svg+xml" />
<script>(function(){try{var s=localStorage.getItem("acg-theme");var m=s||(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");document.documentElement.setAttribute("data-theme",m);document.documentElement.setAttribute("data-skin",(localStorage.getItem("acg-skin")||"bold"));document.documentElement.classList.add("js");}catch(e){}})();</script>
</head>
<body>
<a href="#main" class="sr-only">Skip to content</a>
<header class="site-header">
<div class="wrap">
<a class="brand" href="index.html" aria-label="Arizona Computer Guru home">
<span class="brand__mark" aria-hidden="true"><svg viewBox="0 0 100 104" fill="none" stroke="currentColor" stroke-width="11" stroke-linecap="round" stroke-linejoin="round"><g transform="rotate(20 50 54)"><path d="M61.2 26.2 A30 30 0 1 1 38.8 26.2"/><line x1="50" y1="14" x2="50" y2="50"/></g></svg></span>
<span><span class="brand__name">Arizona Computer Guru</span><br /><span class="brand__since">Concierge IT &middot; Tucson &middot; since 2001</span></span>
</a>
<nav class="nav" aria-label="Primary">
<div class="nav__links" id="navLinks">
<a class="nav__link" href="index.html">Home</a>
<a class="nav__link" href="services.html">Services</a>
<a class="nav__link" href="pricing.html">Pricing</a>
<a class="nav__link nav__link--cta" href="calculator.html">Estimate</a>
<a class="nav__link" href="about.html" aria-current="page">About</a>
<a class="nav__link" href="contact.html">Contact</a>
</div>
<a class="nav__phone" href="tel:+15203048300">520.304.8300</a>
<button class="skin-toggle" id="skinToggle" type="button" aria-label="Switch visual skin (Bold, Midnight, or Verdigris)" title="Switch skin: Bold / Midnight / Verdigris"><span class="sw" aria-hidden="true"></span></button>
<button class="theme-toggle" id="themeToggle" type="button" aria-pressed="false" aria-label="Switch to dark theme" title="Toggle light / dark"><span aria-hidden="true" data-theme-icon>&#9728;</span></button>
<button class="nav__toggle" id="navToggle" type="button" aria-expanded="false" aria-controls="navLinks" aria-label="Open menu">&#8801;</button>
</nav>
</div>
</header>
<main id="main">
<section class="page-head page-head--img ledger">
<div class="wrap">
<div class="reveal">
<p class="eyebrow">Tucson, since 2001</p>
<h1>The IT partner that actually picks up</h1>
<p class="lead">We are not a national chain and we are not venture-backed. We are a local Tucson team that has been here for two decades because we do right by the businesses we serve.</p>
</div>
<figure class="reveal">
<img src="assets/images/about.png" width="1248" height="832" alt="A friendly handshake over a wooden desk with a laptop and a handwritten notebook, an Arizona map framed on the wall." />
</figure>
</div>
</section>
<!-- Origin story -->
<section class="story" aria-labelledby="origin-h">
<div class="wrap">
<div class="story__copy reveal">
<p class="section-tag">Why we work this way <span>/ the short version</span></p>
<h2 id="origin-h">We used to be the company we now warn you about</h2>
<p class="muted">We started in 2001 as a break-fix shop. We charged by the hour, showed up when things broke, and quietly made more money when our clients had more problems. That did not sit right.</p>
<p class="muted">So we built Guru Protection Services: proactive monitoring, transparent published pricing, and month-to-month terms. The point was to put our incentives on the same side of the table as yours. We make more when your systems stay healthy, not when they fail.</p>
<p class="muted">Today we look after businesses across Tucson, from small offices to busy practices and job sites. We have stopped ransomware before a single file was encrypted, replaced failing drives before anyone noticed, and helped owners meet the cyber-insurance requirements that used to keep them up at night.</p>
<blockquote>We built our service the way we'd want to be treated if we were the customer.</blockquote>
</div>
<figure class="story__img reveal">
<img src="assets/images/story.png" width="1248" height="832" alt="Warm afternoon desert light raking across a white stucco wall meeting a clean wooden windowsill." loading="lazy" />
</figure>
</div>
</section>
<!-- Philosophy -->
<section class="home-services ledger" aria-labelledby="phil-h">
<div class="wrap">
<p class="section-tag">What concierge means, concretely <span>/ five choices</span></p>
<h2 id="phil-h">The promises behind the work</h2>
<div class="svc-list">
<article class="svc reveal"><div class="svc__no">01</div><div><h3 class="svc__name">Transparent pricing</h3><p class="svc__desc">Published per-endpoint rates. You know what you pay before you call us. No games, no "call for quote," no fees that appear at the bottom of an invoice.</p></div><div class="svc__meta">$19&ndash;$39 /endpoint</div></article>
<article class="svc reveal"><div class="svc__no">02</div><div><h3 class="svc__name">Local Tucson team</h3><p class="svc__desc">A real office at 7437 E. 22nd St since 2001. When your server dies at 3pm you do not want a ticket, you want someone at your door by 3:45. We can usually be onsite within an hour or two.</p></div><div class="svc__meta">onsite 1&ndash;2 hr</div></article>
<article class="svc reveal"><div class="svc__no">03</div><div><h3 class="svc__name">Proactive, not reactive</h3><p class="svc__desc">24/7 monitoring, automated patching, and alerts that reach us before they reach you. The goal is that you never have to call because something broke.</p></div><div class="svc__meta">24/7 monitoring</div></article>
<article class="svc reveal"><div class="svc__no">04</div><div><h3 class="svc__name">Month-to-month terms</h3><p class="svc__desc">No three-year lock-ins, no early-termination fees. If we stop earning your business, you can leave with 30 days' notice. We would rather keep you by choice.</p></div><div class="svc__meta">cancel in 30 days</div></article>
<article class="svc reveal"><div class="svc__no">05</div><div><h3 class="svc__name">Plain English, always</h3><p class="svc__desc">Many IT people are dismissive or condescending. That is never tolerated here. We are kind, direct, and honest, and we will never make you feel small for asking a question.</p></div><div class="svc__meta">no jargon walls</div></article>
</div>
</div>
</section>
<!-- Big quote band -->
<section aria-labelledby="bq-h">
<div class="wrap" style="max-width:900px;">
<h2 id="bq-h" class="sr-only">Our standard</h2>
<p class="bigquote reveal">You might not choose us. That's okay. But you'll make a better decision because we told you the truth.</p>
<p class="signature reveal">// Arizona Computer Guru, Tucson</p>
</div>
</section>
<section class="cta-band" aria-labelledby="cta-h">
<div class="wrap">
<div class="reveal">
<h2 id="cta-h">Come see for yourself</h2>
<p>Stop by the office, or have us out to look at the server closet that runs hot and the printer that jams every Tuesday. The first conversation is free, and there is no pitch.</p>
</div>
<div class="cta-band__actions reveal">
<a class="btn btn--primary" href="contact.html">Talk to a human <span class="arrow" aria-hidden="true">&rarr;</span></a>
<a class="btn btn--ghost" href="calculator.html">Estimate your cost</a>
</div>
</div>
</section>
</main>
<!-- RADIO TICKER MARQUEE -->
<div class="radio-ticker">
<div class="radio-ticker__track">
<div class="radio-ticker__item"><strong>The Computer Guru Show</strong> Saturdays 9AM on KVOI 1030AM</div>
<div class="radio-ticker__item">Call in: <strong>520-790-2020</strong></div>
<div class="radio-ticker__item">Tucson's trusted tech talk since 2001</div>
<div class="radio-ticker__item"><strong>The Computer Guru Show</strong> Saturdays 9AM on KVOI 1030AM</div>
<div class="radio-ticker__item">Call in: <strong>520-790-2020</strong></div>
<div class="radio-ticker__item">Tucson's trusted tech talk since 2001</div>
</div>
</div>
<!-- EXIT INTENT BANNER -->
<div class="exit-offer" id="exitOffer">
<div class="exit-offer__content">
<div class="exit-offer__message">
<strong>Wait — Free IT Assessment</strong>
<p>Most Tucson businesses overpay for IT. Get a free audit before you go.</p>
</div>
<div class="exit-offer__actions">
<a class="btn btn--primary" href="contact.html">Get Free Assessment</a>
<button class="exit-offer__close" id="closeExit" aria-label="Close banner">&times;</button>
</div>
</div>
</div>
<footer class="site-footer">
<div class="wrap">
<p>&copy; <span id="year">2026</span> Arizona Computer Guru &middot; Protecting Tucson businesses since 2001</p>
<p><a href="tel:+15203048300">520.304.8300</a> &middot; <a href="mailto:info@azcomputerguru.com">info@azcomputerguru.com</a></p>
<p class="disclaimer">Local demonstration build of a proposed azcomputerguru.com (multipage). Pricing reflects published GPS rates and is illustrative for the estimator; a real quote is tailored to your environment. The contact form is not wired to a mailbox. Photography is representational.</p>
</div>
</footer>
<script src="js/app.js"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 104" role="img" aria-label="Arizona Computer Guru">
<g transform="rotate(20 50 54)" fill="none" stroke="#F2922E" stroke-width="11" stroke-linecap="round" stroke-linejoin="round">
<path d="M61.2 26.2 A30 30 0 1 1 38.8 26.2" />
<line x1="50" y1="14" x2="50" y2="50" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 348 B

View File

@@ -1,170 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Estimate your IT cost | Arizona Computer Guru</title>
<meta name="description" content="Build a transparent IT estimate in seconds: endpoints, protection tier, support plan, Microsoft 365, phones, and hosting. No email wall, no sales call." />
<meta name="color-scheme" content="light dark" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@500;600;700&family=Lexend:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500;600;700&family=Fraunces:wght@400;500;600;700&family=Source+Sans+3:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600;700&family=Anton&family=Hanken+Grotesk:wght@400;500;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="icon" href="assets/logo/acg-mark.svg" type="image/svg+xml" />
<script>(function(){try{var s=localStorage.getItem("acg-theme");var m=s||(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");document.documentElement.setAttribute("data-theme",m);document.documentElement.setAttribute("data-skin",(localStorage.getItem("acg-skin")||"bold"));document.documentElement.classList.add("js");}catch(e){}})();</script>
</head>
<body>
<a href="#main" class="sr-only">Skip to content</a>
<header class="site-header">
<div class="wrap">
<a class="brand" href="index.html" aria-label="Arizona Computer Guru home">
<span class="brand__mark" aria-hidden="true"><svg viewBox="0 0 100 104" fill="none" stroke="currentColor" stroke-width="11" stroke-linecap="round" stroke-linejoin="round"><g transform="rotate(20 50 54)"><path d="M61.2 26.2 A30 30 0 1 1 38.8 26.2"/><line x1="50" y1="14" x2="50" y2="50"/></g></svg></span>
<span><span class="brand__name">Arizona Computer Guru</span><br /><span class="brand__since">Concierge IT &middot; Tucson &middot; since 2001</span></span>
</a>
<nav class="nav" aria-label="Primary">
<div class="nav__links" id="navLinks">
<a class="nav__link" href="index.html">Home</a>
<a class="nav__link" href="services.html">Services</a>
<a class="nav__link" href="pricing.html">Pricing</a>
<a class="nav__link" href="calculator.html" aria-current="page">Estimate</a>
<a class="nav__link" href="about.html">About</a>
<a class="nav__link" href="contact.html">Contact</a>
</div>
<a class="nav__phone" href="tel:+15203048300">520.304.8300</a>
<button class="skin-toggle" id="skinToggle" type="button" aria-label="Switch visual skin (Bold, Midnight, or Verdigris)" title="Switch skin: Bold / Midnight / Verdigris"><span class="sw" aria-hidden="true"></span></button>
<button class="theme-toggle" id="themeToggle" type="button" aria-pressed="false" aria-label="Switch to dark theme" title="Toggle light / dark"><span aria-hidden="true" data-theme-icon>&#9728;</span></button>
<button class="nav__toggle" id="navToggle" type="button" aria-expanded="false" aria-controls="navLinks" aria-label="Open menu">&#8801;</button>
</nav>
</div>
</header>
<main id="main">
<section class="page-head ledger">
<div class="wrap reveal">
<p class="eyebrow">Live estimate &middot; no email wall</p>
<h1>Your IT, accounted for</h1>
<p class="lead">Move the numbers, watch the total. This is the same math we would walk you through in person, with nothing hidden behind a "contact sales" button.</p>
</div>
</section>
<section class="calc ledger" id="calculator" aria-labelledby="calc-h" style="padding-top:calc(var(--base)*2);">
<div class="wrap">
<h2 id="calc-h" class="sr-only">IT cost estimator</h2>
<div class="calc__shell">
<div class="calc__grid">
<form class="calc__inputs" id="calcForm" aria-label="IT cost estimator">
<div class="calc__row">
<label for="endpoints">Computers &amp; servers <span class="hint">Every monitored endpoint</span></label>
<div class="calc__control"><div class="stepper" data-step="endpoints">
<button type="button" data-dir="-1" aria-label="Fewer endpoints">&minus;</button>
<input id="endpoints" name="endpoints" type="number" inputmode="numeric" min="0" max="500" value="22" />
<button type="button" data-dir="1" aria-label="More endpoints">+</button>
</div></div>
</div>
<div class="calc__row">
<label for="gpsTier">Protection tier <span class="hint">Per-endpoint monitoring level</span></label>
<div class="calc__control"><select id="gpsTier" name="gpsTier">
<option value="19">GPS-Basic &middot; $19</option>
<option value="26" selected>GPS-Pro &middot; $26</option>
<option value="39">GPS-Advanced &middot; $39</option>
</select></div>
</div>
<div class="calc__row">
<label for="equip">Equipment monitoring <span class="hint">Network gear, printers, NAS. $25/mo</span></label>
<div class="calc__control toggle-row"><span class="switch">
<input type="checkbox" id="equip" name="equip" />
<span class="track" aria-hidden="true"></span><span class="knob" aria-hidden="true"></span>
</span></div>
</div>
<div class="calc__row">
<label for="support">Support plan <span class="hint">Bundled labor hours each month</span></label>
<div class="calc__control"><select id="support" name="support">
<option value="0">None, pay as you go</option>
<option value="200">Essential &middot; $200 (2 hr)</option>
<option value="380" selected>Standard &middot; $380 (4 hr)</option>
<option value="540">Premium &middot; $540 (6 hr)</option>
<option value="850">Priority &middot; $850 (10 hr)</option>
</select></div>
</div>
<div class="calc__row">
<label for="m365">Microsoft 365 users <span class="hint">Business Standard, $14/user</span></label>
<div class="calc__control"><div class="stepper" data-step="m365">
<button type="button" data-dir="-1" aria-label="Fewer Microsoft 365 users">&minus;</button>
<input id="m365" name="m365" type="number" inputmode="numeric" min="0" max="500" value="0" />
<button type="button" data-dir="1" aria-label="More Microsoft 365 users">+</button>
</div></div>
</div>
<div class="calc__row">
<label for="voip">Business phone users <span class="hint">GPS-Voice Standard, $28/user</span></label>
<div class="calc__control"><div class="stepper" data-step="voip">
<button type="button" data-dir="-1" aria-label="Fewer phone users">&minus;</button>
<input id="voip" name="voip" type="number" inputmode="numeric" min="0" max="500" value="0" />
<button type="button" data-dir="1" aria-label="More phone users">+</button>
</div></div>
</div>
<div class="calc__row" style="border-bottom:0;">
<label for="hosting">Web hosting <span class="hint">Managed, with SSL &amp; backups</span></label>
<div class="calc__control"><select id="hosting" name="hosting">
<option value="0" selected>None</option>
<option value="15">Starter &middot; $15</option>
<option value="35">Business &middot; $35</option>
<option value="65">Commerce &middot; $65</option>
</select></div>
</div>
</form>
<div class="calc__out">
<h3>Monthly statement</h3>
<div class="ledger-lines" id="ledgerLines"></div>
<hr class="calc__divider" />
<div class="calc__total" aria-live="polite">
<span class="tlabel">Per month</span>
<span class="tnum mono" id="totalMonthly">$0</span>
</div>
<div class="calc__annual mono" id="totalAnnual">$0 / year</div>
<div class="calc__perep mono" id="perEndpoint">all-in, per endpoint / mo</div>
<a class="btn btn--primary calc__cta" href="contact.html#contact" id="sendEstimate">Send me this estimate <span class="arrow" aria-hidden="true">&rarr;</span></a>
<p class="calc__foot">Estimate only, your real quote is tailored to your setup. No card, no commitment, and we will tell you if you are buying more than you need.</p>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- RADIO TICKER MARQUEE -->
<div class="radio-ticker">
<div class="radio-ticker__track">
<div class="radio-ticker__item"><strong>The Computer Guru Show</strong> Saturdays 9AM on KVOI 1030AM</div>
<div class="radio-ticker__item">Call in: <strong>520-790-2020</strong></div>
<div class="radio-ticker__item">Tucson's trusted tech talk since 2001</div>
<div class="radio-ticker__item"><strong>The Computer Guru Show</strong> Saturdays 9AM on KVOI 1030AM</div>
<div class="radio-ticker__item">Call in: <strong>520-790-2020</strong></div>
<div class="radio-ticker__item">Tucson's trusted tech talk since 2001</div>
</div>
</div>
<!-- EXIT INTENT BANNER -->
<div class="exit-offer" id="exitOffer">
<div class="exit-offer__content">
<div class="exit-offer__message">
<strong>Wait — Free IT Assessment</strong>
<p>Most Tucson businesses overpay for IT. Get a free audit before you go.</p>
</div>
<div class="exit-offer__actions">
<a class="btn btn--primary" href="contact.html">Get Free Assessment</a>
<button class="exit-offer__close" id="closeExit" aria-label="Close banner">&times;</button>
</div>
</div>
</div>
<footer class="site-footer">
<div class="wrap">
<p>&copy; <span id="year">2026</span> Arizona Computer Guru &middot; Protecting Tucson businesses since 2001</p>
<p><a href="tel:+15203048300">520.304.8300</a> &middot; <a href="mailto:info@azcomputerguru.com">info@azcomputerguru.com</a></p>
<p class="disclaimer">Local demonstration build of a proposed azcomputerguru.com (multipage). Pricing reflects published GPS rates and is illustrative for the estimator; a real quote is tailored to your environment. The contact form is not wired to a mailbox. Photography is representational.</p>
</div>
</footer>
<script src="js/app.js"></script>
</body>
</html>

View File

@@ -1,139 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contact | Arizona Computer Guru</title>
<meta name="description" content="Talk to a human in Tucson. Call 520.304.8300, email info@azcomputerguru.com, or visit 7437 E. 22nd St. No pressure, no pitch." />
<meta name="color-scheme" content="light dark" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@500;600;700&family=Lexend:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500;600;700&family=Fraunces:wght@400;500;600;700&family=Source+Sans+3:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600;700&family=Anton&family=Hanken+Grotesk:wght@400;500;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="icon" href="assets/logo/acg-mark.svg" type="image/svg+xml" />
<script>(function(){try{var s=localStorage.getItem("acg-theme");var m=s||(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");document.documentElement.setAttribute("data-theme",m);document.documentElement.setAttribute("data-skin",(localStorage.getItem("acg-skin")||"bold"));document.documentElement.classList.add("js");}catch(e){}})();</script>
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"LocalBusiness","name":"Arizona Computer Guru","image":"assets/images/contact.png","address":{"@type":"PostalAddress","streetAddress":"7437 E. 22nd St","addressLocality":"Tucson","addressRegion":"AZ","postalCode":"85710","addressCountry":"US"},"telephone":"+1-520-304-8300","email":"info@azcomputerguru.com","url":"https://azcomputerguru.com","openingHours":"Mo-Fr 09:00-17:00"}
</script>
</head>
<body>
<a href="#main" class="sr-only">Skip to content</a>
<header class="site-header">
<div class="wrap">
<a class="brand" href="index.html" aria-label="Arizona Computer Guru home">
<span class="brand__mark" aria-hidden="true"><svg viewBox="0 0 100 104" fill="none" stroke="currentColor" stroke-width="11" stroke-linecap="round" stroke-linejoin="round"><g transform="rotate(20 50 54)"><path d="M61.2 26.2 A30 30 0 1 1 38.8 26.2"/><line x1="50" y1="14" x2="50" y2="50"/></g></svg></span>
<span><span class="brand__name">Arizona Computer Guru</span><br /><span class="brand__since">Concierge IT &middot; Tucson &middot; since 2001</span></span>
</a>
<nav class="nav" aria-label="Primary">
<div class="nav__links" id="navLinks">
<a class="nav__link" href="index.html">Home</a>
<a class="nav__link" href="services.html">Services</a>
<a class="nav__link" href="pricing.html">Pricing</a>
<a class="nav__link nav__link--cta" href="calculator.html">Estimate</a>
<a class="nav__link" href="about.html">About</a>
<a class="nav__link" href="contact.html" aria-current="page">Contact</a>
</div>
<a class="nav__phone" href="tel:+15203048300">520.304.8300</a>
<button class="skin-toggle" id="skinToggle" type="button" aria-label="Switch visual skin (Bold, Midnight, or Verdigris)" title="Switch skin: Bold / Midnight / Verdigris"><span class="sw" aria-hidden="true"></span></button>
<button class="theme-toggle" id="themeToggle" type="button" aria-pressed="false" aria-label="Switch to dark theme" title="Toggle light / dark"><span aria-hidden="true" data-theme-icon>&#9728;</span></button>
<button class="nav__toggle" id="navToggle" type="button" aria-expanded="false" aria-controls="navLinks" aria-label="Open menu">&#8801;</button>
</nav>
</div>
</header>
<main id="main">
<section class="contact ledger" id="contact" aria-labelledby="contact-h" style="padding-top:calc(var(--base)*3);">
<div class="wrap">
<div class="contact__intro reveal">
<p class="section-tag">No pressure, no pitch <span>/ let's talk</span></p>
<h1 id="contact-h">Talk to a human</h1>
<p class="muted">Tell us what is frustrating you, or send over an estimate from the calculator. We will give you honest feedback, even if that is "your current setup is fine, here is one thing to fix."</p>
<div class="contact__lines">
<div><span class="k">Phone</span><br /><a class="v" href="tel:+15203048300">520.304.8300</a></div>
<div><span class="k">Email</span><br /><a class="v" href="mailto:info@azcomputerguru.com">info@azcomputerguru.com</a></div>
<div><span class="k">Office</span><br /><span class="v">7437 E. 22nd St, Tucson, AZ 85710</span></div>
<div><span class="k">Hours</span><br /><span class="v">Mon&ndash;Fri 9&ndash;5 &middot; 24/7 emergency for Priority clients</span></div>
</div>
<figure class="office-figure">
<img src="assets/images/contact.png" width="1248" height="832" alt="A warm southwestern stucco storefront at golden hour with a saguaro and the Santa Catalina mountains in the distance, Tucson." loading="lazy" />
<figcaption><span>East side, Tucson</span><span>come say hello</span></figcaption>
</figure>
</div>
<form class="contact__form reveal" id="contactForm" novalidate>
<div class="form-field">
<label for="cf-name">Your name</label>
<input id="cf-name" name="name" type="text" autocomplete="name" required />
</div>
<div class="form-field">
<label for="cf-biz">Business</label>
<input id="cf-biz" name="business" type="text" autocomplete="organization" />
</div>
<div class="form-field">
<label for="cf-contact">Phone or email</label>
<input id="cf-contact" name="contact" type="text" autocomplete="email" required />
</div>
<div class="form-field">
<label for="cf-msg">What can we help with?</label>
<textarea id="cf-msg" name="message"></textarea>
</div>
<button class="btn btn--primary" type="submit">Send message <span class="arrow" aria-hidden="true">&rarr;</span></button>
<p class="form-note" id="formNote" aria-live="polite">We reply the same business day. (Demo build: this form is not wired to a mailbox.)</p>
</form>
</div>
</section>
<section class="faq" id="faq" aria-labelledby="faq-h">
<div class="wrap wrap--narrow">
<p class="section-tag">Straight answers <span>/ ask us anything</span></p>
<h2 id="faq-h">Questions worth asking any IT company</h2>
<div class="faq__list" id="faqList">
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>Will I get a real person, or an offshore call center?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">A real, local person. Our team works out of our Tucson office at 7437 E. 22nd St. You can visit, and after hours you reach an on-call tech who is also local, not a queue overseas.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>What's your contract term?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">Month-to-month. Cancel with 30 days' notice, no early-termination fee. We would rather earn your business every month than trap you in a three-year agreement.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>What happens if I use more support hours than my plan includes?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">Plan hours are used first. After that we draw from any pre-paid block time you have banked ($100 to $150/hr), which never expires. No block time? Overage is billed at $175/hr, and we will always flag it before the meter runs.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>How fast do you respond to an emergency?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">By plan: Standard is 8 hours, Premium 4 hours, Priority 2 hours around the clock. A total outage is escalated immediately regardless of plan, and for local clients we are typically onsite within 1 to 2 hours.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>What security is actually included?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">GPS-Pro and above include advanced EDR, email security, dark-web monitoring, and monthly security-awareness training. GPS-Advanced adds compliance tooling and ransomware rollback. Basic antivirus alone is not enough anymore, so we do not pretend it is.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>Can you help me meet cyber-insurance requirements?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">Yes. GPS-Pro covers most of what insurers ask for: MFA enforcement, EDR, training, and cloud backups, and we will provide documentation for your agent. We work with several Tucson insurance agents regularly.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>What if my team grows or shrinks?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">Billing is per endpoint, so it just follows your headcount. Add three people, add three endpoints; downsize and it drops the next month. No contract amendments, no penalties.</div></div></div>
<div class="faq__item"><button class="faq__q" aria-expanded="false"><span>Do you really publish your pricing?</span><span class="pm" aria-hidden="true">+</span></button><div class="faq__a"><div class="faq__a-inner">You are looking at it. Our rates are on the pricing page and in the estimator. We think hiding prices is a red flag, in any IT company, including us.</div></div></div>
</div>
</div>
</section>
</main>
<!-- RADIO TICKER MARQUEE -->
<div class="radio-ticker">
<div class="radio-ticker__track">
<div class="radio-ticker__item"><strong>The Computer Guru Show</strong> Saturdays 9AM on KVOI 1030AM</div>
<div class="radio-ticker__item">Call in: <strong>520-790-2020</strong></div>
<div class="radio-ticker__item">Tucson's trusted tech talk since 2001</div>
<div class="radio-ticker__item"><strong>The Computer Guru Show</strong> Saturdays 9AM on KVOI 1030AM</div>
<div class="radio-ticker__item">Call in: <strong>520-790-2020</strong></div>
<div class="radio-ticker__item">Tucson's trusted tech talk since 2001</div>
</div>
</div>
<!-- EXIT INTENT BANNER -->
<div class="exit-offer" id="exitOffer">
<div class="exit-offer__content">
<div class="exit-offer__message">
<strong>Wait — Free IT Assessment</strong>
<p>Most Tucson businesses overpay for IT. Get a free audit before you go.</p>
</div>
<div class="exit-offer__actions">
<a class="btn btn--primary" href="contact.html">Get Free Assessment</a>
<button class="exit-offer__close" id="closeExit" aria-label="Close banner">&times;</button>
</div>
</div>
</div>
<footer class="site-footer">
<div class="wrap">
<p>&copy; <span id="year">2026</span> Arizona Computer Guru &middot; Protecting Tucson businesses since 2001</p>
<p><a href="tel:+15203048300">520.304.8300</a> &middot; <a href="mailto:info@azcomputerguru.com">info@azcomputerguru.com</a></p>
<p class="disclaimer">Local demonstration build of a proposed azcomputerguru.com (multipage). Pricing reflects published GPS rates and is illustrative for the estimator; a real quote is tailored to your environment. The contact form is not wired to a mailbox. Photography is representational.</p>
</div>
</footer>
<script src="js/app.js"></script>
</body>
</html>

View File

@@ -1,206 +0,0 @@
/* ===========================================================================
ARIZONA COMPUTER GURU - "BLOWOUT" (radical direction)
Poster brutalism: ultra-condensed display, drenched signal-orange,
scrolling marquee, giant numerals, hard edges, zero ledger calm.
Self-contained (does not use styles.css).
=========================================================================== */
:root {
--ink: #0C0A09; /* near-black canvas */
--ink-2: #16120F; /* raised black panel */
--bone: #F4EDE1; /* primary text */
--bone-2: #B8AE9E; /* secondary */
--hot: #FF5A1F; /* signal orange, used BIG */
--hot-2: #FF8A4D; /* lighter orange for fine text */
--line: rgba(244, 237, 225, 0.16);
--maxw: 1280px;
--f-poster: "Anton", "Arial Narrow", system-ui, sans-serif;
--f-body: "Hanken Grotesk", system-ui, -apple-system, Segoe UI, sans-serif;
--f-mono: "JetBrains Mono", ui-monospace, Consolas, monospace;
}
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
.marquee__track { animation: none !important; }
}
body {
background: var(--ink); color: var(--bone);
font-family: var(--f-body); font-size: 1.0625rem; line-height: 1.5;
-webkit-font-smoothing: antialiased; overflow-x: hidden;
}
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--hot); color: var(--ink); }
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
.wrap { width: min(100% - 3rem, var(--maxw)); margin-inline: auto; }
.hot { color: var(--hot); }
/* ---- Header ------------------------------------------------------------- */
.rx-header {
position: sticky; top: 0; z-index: 50;
background: var(--ink); border-bottom: 2px solid var(--bone);
}
.rx-header .wrap { display: flex; align-items: center; gap: 1.5rem;
height: 68px; }
.rx-brand { font-family: var(--f-poster); font-size: 1.6rem; letter-spacing: 0.02em;
text-transform: uppercase; line-height: 1; }
.rx-brand b { color: var(--hot); }
.rx-nav { margin-left: auto; display: flex; align-items: center; gap: 1.75rem; }
.rx-nav a { font-family: var(--f-mono); font-size: 0.8rem; letter-spacing: 0.08em;
text-transform: uppercase; color: var(--bone-2); }
.rx-nav a:hover { color: var(--hot); }
.rx-cta-sm { border: 2px solid var(--hot); color: var(--bone) !important;
padding: 0.45rem 0.9rem; }
.rx-cta-sm:hover { background: var(--hot); color: var(--ink) !important; }
@media (max-width: 760px) { .rx-nav a:not(.rx-cta-sm) { display: none; } }
/* ---- Hero --------------------------------------------------------------- */
.rx-hero { padding-block: clamp(2.5rem, 7vw, 6rem) clamp(2rem, 5vw, 4rem);
border-bottom: 2px solid var(--bone); position: relative; overflow: hidden; }
.rx-hero__eyebrow { font-family: var(--f-mono); font-size: 0.8rem; letter-spacing: 0.25em;
text-transform: uppercase; color: var(--hot); margin-bottom: 1.5rem; }
.rx-hero h1 {
font-family: var(--f-poster); font-weight: 400; text-transform: uppercase;
font-size: clamp(3.5rem, 16vw, 13rem); line-height: 0.86; letter-spacing: -0.01em;
margin-left: -0.06em;
}
.rx-hero h1 .stroke {
color: transparent; -webkit-text-stroke: 2px var(--bone); text-stroke: 2px var(--bone);
}
.rx-hero__sub { font-size: clamp(1.1rem, 2vw, 1.5rem); color: var(--bone-2);
max-width: 30ch; margin-top: 2rem; }
.rx-hero__cta { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 2.25rem; }
.rx-hero__art {
position: absolute; right: -4%; top: 50%; transform: translateY(-50%);
width: 42vw; max-width: 620px; aspect-ratio: 3/2; pointer-events: none;
filter: grayscale(1) contrast(1.15) brightness(0.62);
-webkit-mask-image: linear-gradient(90deg, transparent, #000 35%);
mask-image: linear-gradient(90deg, transparent, #000 35%);
opacity: 0.55; z-index: -1;
}
.rx-hero__art::after { content: ""; position: absolute; inset: 0; background: var(--hot);
mix-blend-mode: overlay; }
.rx-hero__art img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 900px) { .rx-hero__art { display: none; } }
/* ---- Buttons ------------------------------------------------------------ */
.rx-btn { font-family: var(--f-poster); text-transform: uppercase; letter-spacing: 0.02em;
font-size: 1.15rem; display: inline-flex; align-items: center; gap: 0.6rem;
padding: 0.85rem 1.6rem; border: 2px solid transparent; cursor: pointer; }
.rx-btn--hot { background: var(--hot); color: var(--ink); }
.rx-btn--hot:hover { background: var(--bone); }
.rx-btn--out { border-color: var(--bone); color: var(--bone); }
.rx-btn--out:hover { background: var(--bone); color: var(--ink); }
.rx-btn .x { font-family: var(--f-mono); }
:focus-visible { outline: 3px solid var(--hot); outline-offset: 3px; }
/* ---- Marquee ------------------------------------------------------------ */
.marquee { background: var(--hot); color: var(--ink); border-bottom: 2px solid var(--bone);
overflow: hidden; padding-block: 0.7rem; }
.marquee__track { display: inline-flex; white-space: nowrap; will-change: transform;
animation: marquee 26s linear infinite; }
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee span { font-family: var(--f-poster); text-transform: uppercase;
font-size: 1.4rem; letter-spacing: 0.03em; padding-inline: 1.25rem; }
.marquee span::after { content: "\273F"; margin-left: 2.5rem; opacity: 0.6; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* ---- Section scaffold --------------------------------------------------- */
.rx-sec { padding-block: clamp(3rem, 7vw, 6.5rem); border-bottom: 2px solid var(--bone); position: relative; }
.rx-kicker { font-family: var(--f-mono); font-size: 0.8rem; letter-spacing: 0.22em;
text-transform: uppercase; color: var(--hot); display: flex; gap: 1rem; align-items: center; }
.rx-kicker::before { content: ""; width: 40px; height: 2px; background: var(--hot); }
.rx-h2 { font-family: var(--f-poster); text-transform: uppercase; font-weight: 400;
font-size: clamp(2.4rem, 6vw, 4.5rem); line-height: 0.92; margin-top: 1rem; }
.rx-ghost { position: absolute; right: 2%; top: 0.5rem; font-family: var(--f-poster);
font-size: clamp(6rem, 18vw, 16rem); line-height: 1; color: transparent;
-webkit-text-stroke: 1px var(--line); pointer-events: none; user-select: none; z-index: 0; }
.rx-sec > .wrap { position: relative; z-index: 1; }
/* ---- Services (giant rows) ---------------------------------------------- */
.rx-svc { display: grid; grid-template-columns: 4.5rem 1fr auto; align-items: baseline;
gap: 1.5rem; padding-block: 1.4rem; border-top: 2px solid var(--line);
transition: background 0.18s, padding-left 0.18s; }
.rx-svc:last-child { border-bottom: 2px solid var(--line); }
.rx-svc:hover { background: var(--ink-2); padding-left: 1rem; }
.rx-svc__n { font-family: var(--f-mono); color: var(--hot); font-size: 0.95rem; }
.rx-svc__name { font-family: var(--f-poster); text-transform: uppercase;
font-size: clamp(1.6rem, 3.6vw, 2.6rem); line-height: 0.95; }
.rx-svc__d { color: var(--bone-2); font-size: 0.98rem; max-width: 52ch; margin-top: 0.4rem; }
.rx-svc__meta { font-family: var(--f-mono); color: var(--hot-2); font-size: 0.85rem;
white-space: nowrap; text-align: right; }
@media (max-width: 640px) {
.rx-svc { grid-template-columns: 2.5rem 1fr; }
.rx-svc__meta { grid-column: 2; text-align: left; }
}
/* ---- Pricing (blowout numerals) ----------------------------------------- */
.rx-prices { display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 2.5rem;
border: 2px solid var(--bone); }
.rx-price { padding: clamp(1.5rem, 3vw, 2.5rem); border-right: 2px solid var(--bone); }
.rx-price:last-child { border-right: 0; }
.rx-price--pop { background: var(--hot); color: var(--ink); }
.rx-price__tier { font-family: var(--f-mono); text-transform: uppercase; letter-spacing: 0.1em;
font-size: 0.85rem; }
.rx-price__big { font-family: var(--f-poster); font-size: clamp(4rem, 11vw, 8.5rem);
line-height: 0.8; margin-top: 0.75rem; }
.rx-price__u { font-family: var(--f-mono); font-size: 0.8rem; color: var(--bone-2); display: block;
margin-top: 0.75rem; }
.rx-price--pop .rx-price__u { color: var(--ink); opacity: 0.7; }
.rx-price__list { list-style: none; padding: 0; margin-top: 1.25rem; display: grid; gap: 0.4rem;
font-size: 0.9rem; color: var(--bone-2); }
.rx-price--pop .rx-price__list { color: var(--ink); }
.rx-price__list li::before { content: "+ "; font-family: var(--f-mono); }
@media (max-width: 760px) {
.rx-prices { grid-template-columns: 1fr; }
.rx-price { border-right: 0; border-bottom: 2px solid var(--bone); }
.rx-price:last-child { border-bottom: 0; }
}
/* ---- Calculator teaser -------------------------------------------------- */
.rx-calc { background: var(--ink-2); }
.rx-calc .wrap { display: grid; grid-template-columns: 1.4fr auto; gap: 2rem; align-items: center; }
.rx-calc__big { font-family: var(--f-poster); text-transform: uppercase;
font-size: clamp(2.2rem, 6vw, 4.5rem); line-height: 0.9; }
.rx-calc p { color: var(--bone-2); margin-top: 1rem; max-width: 46ch; }
@media (max-width: 760px) { .rx-calc .wrap { grid-template-columns: 1fr; } }
/* ---- CTA drench --------------------------------------------------------- */
.rx-cta { background: var(--hot); color: var(--ink); border-bottom: 0; text-align: center; }
.rx-cta__big { font-family: var(--f-poster); text-transform: uppercase;
font-size: clamp(3rem, 13vw, 10rem); line-height: 0.85; }
.rx-cta__row { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-top: 2rem; }
.rx-cta .rx-btn--hot { background: var(--ink); color: var(--hot); }
.rx-cta .rx-btn--hot:hover { background: var(--bone); color: var(--ink); }
.rx-cta .rx-btn--out { border-color: var(--ink); color: var(--ink); }
.rx-cta .rx-btn--out:hover { background: var(--ink); color: var(--hot); }
/* ---- Footer ------------------------------------------------------------- */
.rx-footer { padding-block: 2.5rem; }
.rx-footer .wrap { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; }
.rx-footer p { font-family: var(--f-mono); font-size: 0.8rem; color: var(--bone-2); }
.rx-footer a { color: var(--bone); }
.rx-footer a:hover { color: var(--hot); }
.rx-note { width: 100%; font-size: 0.72rem; color: var(--bone-2); opacity: 0.7;
border-top: 2px solid var(--line); padding-top: 1rem; margin-top: 0.5rem; }
/* reveal */
.rx-up { opacity: 0; transform: translateY(18px); transition: opacity 0.6s cubic-bezier(0.2,0.7,0.2,1), transform 0.6s cubic-bezier(0.2,0.7,0.2,1); }
.rx-up.in { opacity: 1; transform: none; }
/* ---- narrow-screen polish ---------------------------------------------- */
@media (max-width: 480px) {
.rx-header .wrap { gap: 0.75rem; }
.rx-brand { font-size: 1.15rem; }
.rx-cta-sm { font-size: 0.72rem; padding: 0.4rem 0.6rem; }
.rx-hero__cta { flex-direction: column; align-items: stretch; }
.rx-hero__cta .rx-btn { justify-content: center; }
.marquee span { font-size: 1.1rem; }
.rx-calc .rx-btn { justify-self: start; }
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

View File

@@ -1 +0,0 @@
Error: bundled detector not found.

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env bash
set -u
ROOT=/d/ClaudeTools
GROK="$ROOT/.claude/skills/grok/scripts/ask-grok.sh"
OUT="$ROOT/projects/acg-website-showcase/multipage/assets/images"
cd "$ROOT"
echo "=== [1/3] services / hardware ==="
bash "$GROK" image "Photorealistic editorial close-up of a tidy small-office network setup in warm afternoon light: a clean wall-mounted patch panel and a small network switch with neatly dressed cables on a light wooden shelf against a smooth white stucco wall. Orderly, honest, premium, no logos, no text. Warm cream, tan and soft amber palette, gentle film grain, shallow depth of field. No people. Wide 3:2 landscape." "$OUT/services.png"
echo "=== [2/3] about / relationship ==="
bash "$GROK" image "Photorealistic editorial photograph, warm afternoon window light: a friendly handshake across a light-wood desk in a small Tucson office, mid-shot focusing on the two hands meeting above the desk, with a modern laptop and an open paper notebook nearby. Genuine, human, welcoming. Warm cream and tan palette, soft fine film grain, shallow depth of field. No logos, no visible faces, no text. Wide 3:2 landscape." "$OUT/about.png"
echo "=== [3/3] contact / Tucson exterior ==="
bash "$GROK" image "Photorealistic golden-hour photograph: the exterior of a modest single-story southwestern commercial building with warm hand-troweled stucco walls and a clean simple storefront, a saguaro cactus and the soft silhouette of the Santa Catalina mountains in the distance, Tucson Arizona. Calm, local, welcoming. No signage text, no people, no logos. Warm cream and amber palette, soft film grain. Wide 3:2 landscape." "$OUT/contact.png"
echo "=== DONE ==="
ls -la "$OUT"

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env bash
set -u
ROOT=/d/ClaudeTools
GROK="$ROOT/.claude/skills/grok/scripts/ask-grok.sh"
OUT="$ROOT/projects/acg-website-showcase/multipage/assets/images/verdigris"
mkdir -p "$OUT"
cd "$ROOT"
echo "=== [1/4] hero: copper gate latch ==="
bash "$GROK" image "Photorealistic documentary close-up: a verdigris-patinated copper gate latch on a whitewashed stucco wall, soft cool morning side light, the latch in sharp focus and the plaster softly blurred behind it. Neutral-to-cool white balance, desaturated palette, the verdigris blue-green patina is the only saturated hue in frame, shallow depth of field, fine grain. No people, no text, no lens flare. Wide 3:2 landscape." "$OUT/hero.png"
echo "=== [2/4] services: patch panel labeling ==="
bash "$GROK" image "Photorealistic documentary photo: a pair of hands labeling a network patch panel with small neat handwritten tags, careful and human, cool neutral light, shallow depth of field, desaturated palette with a faint hint of verdigris green. Industrial, orderly, transparent process. No faces, no logos, no text on screen. Wide 3:2 landscape." "$OUT/services.png"
echo "=== [3/4] about: weathered enamel storefront sign ==="
bash "$GROK" image "Photorealistic documentary photo: a weathered hand-painted enamel storefront service sign mounted on a whitewashed Tucson stucco wall, cared-for but not glossy, the lettering soft and partly out of focus, partial sidewalk and plaster visible. Cool neutral white balance, side light, desaturated palette with verdigris-green and aged-metal accents. No people. Wide 3:2 landscape." "$OUT/about.png"
echo "=== [4/4] contact: cool Tucson storefront ==="
bash "$GROK" image "Photorealistic documentary photo: the exterior of a tidy 1950s single-story Tucson stucco storefront in cool overcast morning light, whitewashed plaster walls, a weathered copper-patina door pull and trim, clean simple windows. Calm, local, cared-for. Cool neutral white balance, desaturated palette, verdigris-green the only saturated hue. No signage text, no people. Wide 3:2 landscape." "$OUT/contact.png"
echo "=== DONE ==="; ls -la "$OUT"

Some files were not shown because too many files have changed in this diff Show More