Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
<h1>my site</h1>
# Contador (Tema Marrom e Branco)

<p>não estilisa e não aparece a imagem
mais é pra ser assim</p>
Um contador simples, responsivo e acessível com paleta marrom e branco.

https://www.canva.com/design/DAGTM361VcI/oW0VIRT4JWtolufyGCGSNQ/edit
## Como usar

- Abra o arquivo `index.html` diretamente no navegador (clique duas vezes ou use um servidor estático).
- Use os botões para aumentar, diminuir e redefinir.
- Ajuste o campo "Passo" para definir de quanto em quanto o valor muda.

## Atalhos de teclado

- `↑`, `+` ou `=`: aumenta o valor
- `↓`, `-` ou `_`: diminui o valor
- `R` ou `0`: redefine para 0

## Acessibilidade

- Leitura do valor com `aria-live` e rótulos claros.
- Foco visível nos botões e campos.
- Link de pular para o conteúdo.

## Estrutura do projeto

- `index.html` — marcação e estrutura
- `styles.css` — tema marrom e branco
- `script.js` — lógica do contador e atalhos

## Personalização

As cores principais estão em variáveis CSS no `:root` do `styles.css` (por exemplo, `--brown-800`, `--offwhite`). Ajuste-as para variar o tom do tema.

## Referência de design

Inspirado neste design: [Canva](https://www.canva.com/design/DAGTM361VcI/oW0VIRT4JWtolufyGCGSNQ/edit)
53 changes: 53 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Contador — Marrom & Branco</title>
<meta name="description" content="Um contador simples com tema marrom e branco." />
<link rel="stylesheet" href="./styles.css" />
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='0.9em' font-size='90'%3E%2B%3C/text%3E%3C/svg%3E">
</head>
<body>
<a class="skip-link" href="#main">Pular para o conteúdo</a>

<header class="site-header">
<h1 class="site-title">Contador</h1>
</header>

<main id="main" class="container" role="main">
<section class="counter" aria-labelledby="counter-heading">
<h2 id="counter-heading" class="visually-hidden">Controles do contador</h2>

<div class="display" role="status" aria-live="polite" aria-atomic="true" aria-label="Valor atual do contador">
<span id="value" class="value" data-testid="value">0</span>
</div>

<form class="controls" autocomplete="off" onsubmit="return false;">
<div class="step-field">
<label for="step">Passo</label>
<input id="step" name="step" type="number" inputmode="numeric" min="1" step="1" value="1" aria-describedby="step-help" />
<small id="step-help" class="help">Quantia adicionada ou subtraída a cada clique.</small>
</div>

<div class="buttons">
<button type="button" id="decrement" class="btn btn-secondary" aria-label="Diminuir">−</button>
<button type="button" id="reset" class="btn btn-ghost" aria-label="Redefinir">Redefinir</button>
<button type="button" id="increment" class="btn btn-primary" aria-label="Aumentar">+</button>
</div>
</form>

<div class="shortcuts" aria-live="polite">
<p class="hint">Atalhos: ↑/+/= aumenta, ↓/− diminui, R ou 0 redefine.</p>
</div>
</section>
</main>

<footer class="site-footer">
<p>Feito com tema marrom e branco.</p>
</footer>

<script src="./script.js" defer></script>
</body>
</html>

102 changes: 102 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
(function () {
"use strict";

/** @type {HTMLElement | null} */
const valueElement = document.getElementById("value");
/** @type {HTMLInputElement | null} */
const stepInput = /** @type {HTMLInputElement | null} */ (document.getElementById("step"));
/** @type {HTMLButtonElement | null} */
const incrementButton = /** @type {HTMLButtonElement | null} */ (document.getElementById("increment"));
/** @type {HTMLButtonElement | null} */
const decrementButton = /** @type {HTMLButtonElement | null} */ (document.getElementById("decrement"));
/** @type {HTMLButtonElement | null} */
const resetButton = /** @type {HTMLButtonElement | null} */ (document.getElementById("reset"));

if (!valueElement || !stepInput || !incrementButton || !decrementButton || !resetButton) {
return;
}

/** @type {number} */
let currentValue = 0;

function coerceStep(value) {
const parsed = parseInt(String(value), 10);
if (Number.isNaN(parsed) || parsed < 1) return 1;
return parsed;
}

function getStep() {
return coerceStep(stepInput.value);
}

function announce(value) {
const parent = valueElement.parentElement;
if (parent) {
parent.setAttribute("aria-label", `Valor atual do contador: ${value}`);
}
}

function render(value) {
valueElement.textContent = String(value);
announce(value);
}

function setValue(next) {
currentValue = next;
render(currentValue);
}

function increment() {
setValue(currentValue + getStep());
}

function decrement() {
setValue(currentValue - getStep());
}

function reset() {
setValue(0);
}

// Button interactions
incrementButton.addEventListener("click", increment);
decrementButton.addEventListener("click", decrement);
resetButton.addEventListener("click", reset);

// Normalize step input
stepInput.addEventListener("change", function () {
const normalized = getStep();
stepInput.value = String(normalized);
});

// Keyboard shortcuts (global)
document.addEventListener("keydown", function (event) {
// Avoid interfering when typing in inputs other than the body
const target = /** @type {HTMLElement} */ (event.target);
const isTypingInNumberInput = target instanceof HTMLInputElement && target.type === "number";
if (isTypingInNumberInput) {
return;
}

const key = event.key;
if (key === "ArrowUp" || key === "+" || key === "=") {
event.preventDefault();
increment();
return;
}
if (key === "ArrowDown" || key === "-" || key === "_") {
event.preventDefault();
decrement();
return;
}
if (key === "r" || key === "R" || key === "0") {
event.preventDefault();
reset();
return;
}
});

// Initial render
render(currentValue);
})();

Loading