<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Norberto Krucheski</title>
    <description>The latest articles on Forem by Norberto Krucheski (@norbertok).</description>
    <link>https://forem.com/norbertok</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F695769%2Fb266e799-c6e9-4d80-b8e1-e9500ffeb977.jpg</url>
      <title>Forem: Norberto Krucheski</title>
      <link>https://forem.com/norbertok</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/norbertok"/>
    <language>en</language>
    <item>
      <title>Empecé a programar a las 9 de la noche. Eran las 4 de la mañana y no quería parar.</title>
      <dc:creator>Norberto Krucheski</dc:creator>
      <pubDate>Tue, 07 Apr 2026 18:34:53 +0000</pubDate>
      <link>https://forem.com/norbertok/empece-a-programar-a-las-9-de-la-noche-eran-las-4-de-la-manana-y-no-queria-parar-1nig</link>
      <guid>https://forem.com/norbertok/empece-a-programar-a-las-9-de-la-noche-eran-las-4-de-la-manana-y-no-queria-parar-1nig</guid>
      <description>&lt;p&gt;Son las 11 de la noche. Abrí el editor con la idea de resolver una cosa puntual, una sola. Dos horas después sigo acá, el proyecto avanzó más que en toda la semana anterior, y lo último que quiero hacer es cerrar la computadora.&lt;/p&gt;

&lt;p&gt;No es que no tenga sueño. Es que parar se siente mal.&lt;/p&gt;




&lt;h2&gt;
  
  
  No es tirar prompts al azar
&lt;/h2&gt;

&lt;p&gt;Quiero aclarar algo antes de seguir, porque si no, esto puede sonar a la historia de cualquiera que descubrió ChatGPT y se emocionó.&lt;/p&gt;

&lt;p&gt;Trabajo en la industria hace más de 15 años. Cuando arranco un proyecto, no abro el chat y empiezo a pedir código. Primero pienso el producto. Armo un PRD con el detalle necesario: qué problema resuelve, quién lo usa, qué no entra en scope. Después pienso la arquitectura. Qué stack, por qué, cómo se comunican las partes. Si hay una API involucrada, escribo la documentación técnica antes de tocar una sola línea.&lt;/p&gt;

&lt;p&gt;Recién ahí, con todo eso claro, empiezo a iterar con la IA.&lt;/p&gt;

&lt;p&gt;Y esa diferencia lo cambia todo. Cuando sabés exactamente lo que querés, cuando el contexto está bien armado y el prompt refleja eso, la IA no alucina. No te devuelve algo genérico que tenés que reescribir. Te devuelve exactamente lo que necesitás, en el stack que elegiste, con la arquitectura que definiste.&lt;/p&gt;

&lt;p&gt;Eso es lo que no se dice mucho: la IA no reemplaza el pensamiento. Lo amplifica. Si llegás con las ideas claras, el resultado es bueno. Si llegás sin saber qué querés, el resultado es ruido.&lt;/p&gt;




&lt;h2&gt;
  
  
  El loop que no ves venir
&lt;/h2&gt;

&lt;p&gt;El problema no es que la IA funcione mal. El problema es que funciona muy bien.&lt;/p&gt;

&lt;p&gt;Un proyecto que antes me llevaba una semana, hoy lo resuelvo en un día. Funcional, escalable, con el código que yo hubiera escrito si tuviera el tiempo. Eso genera una descarga parecida a la dopamina: cada feature que cierra, cada endpoint que responde, cada componente que aparece en pantalla exactamente como lo imaginaste. El momentum es real y es adictivo.&lt;/p&gt;

&lt;p&gt;Y cuando algo tiene tanto momentum, parar se siente como perder.&lt;/p&gt;

&lt;p&gt;Empezás a estirar la sesión. "Una cosa más y cierro." Esa cosa lleva a otra. Y esa otra lleva a otra. No porque estés bloqueado, sino porque todo fluye. Es la versión tech del binge — no parás porque el siguiente episodio arranca solo.&lt;/p&gt;

&lt;p&gt;Lo que no notás en ese momento es que estás en un estado alterado de productividad. El cerebro en modo flow, alimentado por resultados rápidos y constantes. No es una sensación mala. Es exactamente eso lo que lo hace difícil de cortar.&lt;/p&gt;




&lt;h2&gt;
  
  
  El momento en que me di cuenta
&lt;/h2&gt;

&lt;p&gt;No fue un momento dramático. No rompí nada, no perdí trabajo.&lt;/p&gt;

&lt;p&gt;El patrón era siempre el mismo. Me sentaba a la noche a avanzar un poco. El proyecto estaba en un 70%, ese 70% lo había hecho en un día o dos, y en mi cabeza solo quedaba un 30% — algo que calculaba en una o dos horas. Fácil. Rápido. "Termino esto y me acuesto."&lt;/p&gt;

&lt;p&gt;Eran las 9 de la noche. Cuando levanté la vista del monitor eran las 4 de la mañana.&lt;/p&gt;

&lt;p&gt;No porque algo hubiera salido mal. Al contrario: todo fluía, cada iteración cerraba bien, y ese 30% que quedaba siempre tenía un poco más para refinar, para mejorar, para dejar bien. El proyecto estaba avanzando perfecto — y eso era exactamente el problema. Cuando las cosas van bien no hay señal de parada. El cerebro no tiene motivo para frenar.&lt;/p&gt;

&lt;p&gt;Me di cuenta de que no era cansancio lo que me hacía cerrar la computadora. Era el horario, o que alguien me escribía, o que físicamente ya no podía más. Nunca era una decisión.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lo que aprendí
&lt;/h2&gt;

&lt;p&gt;La IA no te vuelve adicto porque sea fácil. Te vuelve adicto porque, si sabés usarla, es genuinamente poderosa. Y eso es más peligroso que si fuera una herramienta mediocre.&lt;/p&gt;

&lt;p&gt;Lo primero que cambié fue dejar de programar de noche por defecto. No siempre se puede, pero cuando tengo la opción, lo evito. La noche y el momentum son una combinación difícil de cortar.&lt;/p&gt;

&lt;p&gt;Y cuando sí me siento a la noche, entro con dos cosas claras: una hora de corte y una meta específica. No "voy a avanzar un poco" — eso no existe. Algo concreto: estas dos features, este módulo, este endpoint. Cuando lo terminé, cierro. Sin negociar.&lt;/p&gt;

&lt;p&gt;Parece simple. Y lo es. Pero la diferencia entre &lt;strong&gt;"voy a avanzar un poco"&lt;/strong&gt; y &lt;strong&gt;"voy a terminar estas dos cosas y cierro"&lt;/strong&gt; es la diferencia entre las 11 de la noche y las 4 de la mañana.&lt;/p&gt;

&lt;p&gt;El proyecto va a seguir mañana. Siempre sigue.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;¿Te pasó algo parecido? Me interesa saber si el patrón es el mismo cuando el contexto y el nivel de experiencia cambian.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Hice una app de escritorio para procesar imágenes — sin nube, sin cuenta, todo local</title>
      <dc:creator>Norberto Krucheski</dc:creator>
      <pubDate>Thu, 26 Feb 2026 18:11:39 +0000</pubDate>
      <link>https://forem.com/norbertok/hice-una-app-de-escritorio-para-procesar-imagenes-sin-nube-sin-cuenta-todo-local-2101</link>
      <guid>https://forem.com/norbertok/hice-una-app-de-escritorio-para-procesar-imagenes-sin-nube-sin-cuenta-todo-local-2101</guid>
      <description>&lt;p&gt;Cada vez que necesitaba convertir una imagen a WebP, redimensionar o sacarle los metadatos EXIF, terminaba en alguna página random que te pide subir el archivo a un servidor. Tus fotos viajando a quién sabe dónde, para una operación que cualquier computadora moderna puede hacer en milisegundos.&lt;/p&gt;

&lt;p&gt;Me cansé de eso y armé &lt;strong&gt;Pixora&lt;/strong&gt;: una app de escritorio, open source, que procesa imágenes 100% en tu máquina. Sin internet, sin cuenta, sin nube.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NorbertOSK" rel="noopener noreferrer"&gt;
        NorbertOSK
      &lt;/a&gt; / &lt;a href="https://github.com/NorbertOSK/pixora" rel="noopener noreferrer"&gt;
        pixora
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/NorbertOSK/pixora/src/assets/img/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNorbertOSK%2Fpixora%2Fsrc%2Fassets%2Fimg%2Flogo.png" alt="Pixora Logo" width="96"&gt;&lt;/a&gt;
  &lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Pixora&lt;/h1&gt;
&lt;/div&gt;
  &lt;p&gt;&lt;strong&gt;Local-first image processing. No cloud. No account.&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;
    &lt;a href="https://github.com/NorbertOSK/pixora/README.md" rel="noopener noreferrer"&gt;🇺🇸 English&lt;/a&gt;  | 
    &lt;a href="https://github.com/NorbertOSK/pixora/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt;  | 
    &lt;a href="https://github.com/NorbertOSK/pixora/README.pt-BR.md" rel="noopener noreferrer"&gt;🇧🇷 Português&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667"&gt;&lt;img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="MIT License"&gt;&lt;/a&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/bbcd831059b7bf27d67a3a5eda876823f49ceae7f294408c2cae1c9f19c63687/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667"&gt;&lt;img src="https://camo.githubusercontent.com/bbcd831059b7bf27d67a3a5eda876823f49ceae7f294408c2cae1c9f19c63687/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667" alt="Platforms"&gt;&lt;/a&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3adce1f628973855aca702ee1df09e0761c7c0c67b7400dde71dbab42c327dfe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6275696c74253230776974682d5461757269253230322d3234433844382e737667"&gt;&lt;img src="https://camo.githubusercontent.com/3adce1f628973855aca702ee1df09e0761c7c0c67b7400dde71dbab42c327dfe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6275696c74253230776974682d5461757269253230322d3234433844382e737667" alt="Built with Tauri"&gt;&lt;/a&gt;
  &lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Pixora is a free, open-source desktop app for image processing. Convert formats, resize, remove backgrounds with AI, and strip metadata — all 100% locally on your machine, with no internet required after setup.&lt;/p&gt;

  
    

    &lt;span class="m-1"&gt;app.mp4&lt;/span&gt;
  

  

  



&lt;p&gt;Built by &lt;a href="https://norbertok.com" rel="nofollow noopener noreferrer"&gt;Norberto Krucheski&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Download&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Installers are automatically built for every release via GitHub Actions.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Download&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;⬇ Download for Windows (.exe)&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;macOS&lt;/strong&gt; (Apple Silicon M1 or higher)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;⬇ Download for macOS (.dmg)&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;⬇ Download for Linux (.AppImage / .deb)&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Just download, install, and run — no account, no setup, no cloud.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Format Conversion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Convert between WebP, JPEG, and PNG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quality Control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Adjustable quality slider (1–100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Smart Resize&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10 built-in presets (hero, blog, avatar, 4K…) + custom dimensions. Aspect ratio always preserved.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EXIF &amp;amp; Metadata&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;View full metadata (camera, GPS, date, exposure…) and strip&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NorbertOSK/pixora" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;







&lt;h2&gt;
  
  
  Qué hace
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conversión de formato&lt;/strong&gt; — WebP, JPEG, PNG, con un slider de calidad&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redimensionar&lt;/strong&gt; — 10 presets (hero, blog, avatar, 4K) o dimensiones custom. Siempre preserva el aspect ratio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ver y eliminar metadatos EXIF&lt;/strong&gt; — cámara, GPS, fecha, todo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remover fondo con IA&lt;/strong&gt; — modelo ONNX local, sin API key, funciona offline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Procesamiento masivo&lt;/strong&gt; — arrastrás un montón de imágenes y las procesa en paralelo. Exportás todo como ZIP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vista antes/después&lt;/strong&gt; — slider interactivo para comparar el resultado&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todo esto funciona sin conexión a internet (después de la primera descarga del modelo de IA).&lt;/p&gt;




&lt;h2&gt;
  
  
  Por qué Tauri 2 + Rust en vez de Electron
&lt;/h2&gt;

&lt;p&gt;Electron es genial para muchas cosas, pero para procesar imágenes necesitaba velocidad real. No "velocidad aceptable", sino que un batch de 8 fotos pesadas no trabe la interfaz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tauri 2&lt;/strong&gt; me dejó combinar lo mejor de dos mundos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El frontend es &lt;strong&gt;React 18 con TypeScript&lt;/strong&gt;. Toda la UI, los paneles, la grilla de imágenes, el slider antes/después. React maneja el estado y los re-renders, pero nunca toca un archivo de imagen directamente.&lt;/li&gt;
&lt;li&gt;El backend es &lt;strong&gt;Rust puro&lt;/strong&gt;. Resize con filtro Lanczos3, conversión de formatos, limpieza de EXIF recodificando desde cero, inferencia del modelo ONNX para remover fondos, y creación de ZIPs. Todo compilado a código nativo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust corre a velocidad de C sin garbage collector. Sin pausas, sin demoras random. Las imágenes se procesan en paralelo usando un pool de workers dimensionado a los núcleos del CPU. En un Mac con chip M, procesar 8 imágenes tarda prácticamente lo mismo que procesar 1.&lt;/p&gt;




&lt;h2&gt;
  
  
  El detalle técnico que más me costó
&lt;/h2&gt;

&lt;p&gt;La comunicación entre React y Rust pasa por un canal IPC que expone Tauri. La primera idea obvia fue: pasar la imagen como base64 por ese canal. Funciona, pero bloquea el thread de JavaScript en cada llamada. Con una imagen grande se nota. Con un batch de 10, la UI se congela.&lt;/p&gt;

&lt;p&gt;La solución fue cambiar el enfoque: &lt;strong&gt;todo el procesamiento corre en Rust, y al frontend solo le devuelvo la ruta de un archivo temporal&lt;/strong&gt;. Menos de 200 bytes viajando por el IPC en vez de megabytes de base64. La interfaz lee ese archivo una sola vez para mostrarlo.&lt;/p&gt;

&lt;p&gt;Parece un cambio chico, pero fue lo que hizo que el procesamiento masivo funcione sin que la app se trabe.&lt;/p&gt;




&lt;h2&gt;
  
  
  Remoción de fondo con IA — offline
&lt;/h2&gt;

&lt;p&gt;Esto es lo que más me gustó implementar. Usa &lt;strong&gt;IS-Net&lt;/strong&gt;, un modelo ONNX cuantizado que pesa ~42 MB. Se descarga la primera vez que lo usás y después funciona completamente offline.&lt;/p&gt;

&lt;p&gt;La inferencia corre en &lt;strong&gt;ONNX Runtime para Rust&lt;/strong&gt; (&lt;code&gt;ort&lt;/code&gt; crate), directamente en CPU. No necesitás API key, no necesitás GPU, no necesitás nada externo.&lt;/p&gt;

&lt;p&gt;El modelo se cachea en:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sistema&lt;/th&gt;
&lt;th&gt;Ubicación&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;macOS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/Library/Application Support/pixora/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%LOCALAPPDATA%\pixora\&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/share/pixora/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Stack completo
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capa&lt;/th&gt;
&lt;th&gt;Tecnología&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Desktop&lt;/td&gt;
&lt;td&gt;Tauri 2 (Rust + WebView nativo)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 18 + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bundler&lt;/td&gt;
&lt;td&gt;Vite 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estilos&lt;/td&gt;
&lt;td&gt;Tailwind CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estado&lt;/td&gt;
&lt;td&gt;Zustand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Imágenes&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;image&lt;/code&gt; crate (resize, compress, convert)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadatos&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kamadak-exif&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IA&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ort&lt;/code&gt; (ONNX Runtime) + IS-Net&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ZIP&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;zip&lt;/code&gt; crate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Probalo
&lt;/h2&gt;

&lt;p&gt;Hay instaladores listos para descargar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt; — &lt;code&gt;.exe&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS&lt;/strong&gt; (Apple Silicon) — &lt;code&gt;.dmg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux&lt;/strong&gt; — &lt;code&gt;.AppImage&lt;/code&gt; / &lt;code&gt;.deb&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;Descargá la última versión acá&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O si preferís compilar desde el código fuente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/NorbertOSK/pixora.git
&lt;span class="nb"&gt;cd &lt;/span&gt;pixora
bun &lt;span class="nb"&gt;install
&lt;/span&gt;bun start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;La primera vez tarda unos minutos porque compila el backend de Rust. Después arranca rápido.&lt;/p&gt;


&lt;h2&gt;
  
  
  Privacidad
&lt;/h2&gt;

&lt;p&gt;Tus imágenes &lt;strong&gt;nunca salen de tu máquina&lt;/strong&gt;. No hay servidor, no hay telemetría, no hay analytics. El modelo de IA se descarga una sola vez y listo.&lt;/p&gt;



&lt;p&gt;Si te resulta útil, una estrellita en el repo ayuda un montón 😁&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NorbertOSK" rel="noopener noreferrer"&gt;
        NorbertOSK
      &lt;/a&gt; / &lt;a href="https://github.com/NorbertOSK/pixora" rel="noopener noreferrer"&gt;
        pixora
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/NorbertOSK/pixora/src/assets/img/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNorbertOSK%2Fpixora%2Fsrc%2Fassets%2Fimg%2Flogo.png" alt="Pixora Logo" width="96"&gt;&lt;/a&gt;
  &lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Pixora&lt;/h1&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Local-first image processing. No cloud. No account.&lt;/strong&gt;&lt;/p&gt;
&lt;br&gt;
  &lt;p&gt;&lt;br&gt;
    &lt;a href="https://github.com/NorbertOSK/pixora/README.md" rel="noopener noreferrer"&gt;🇺🇸 English&lt;/a&gt;  | &lt;br&gt;
    &lt;a href="https://github.com/NorbertOSK/pixora/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt;  | &lt;br&gt;
    &lt;a href="https://github.com/NorbertOSK/pixora/README.pt-BR.md" rel="noopener noreferrer"&gt;🇧🇷 Português&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;br&gt;
  &lt;p&gt;&lt;br&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667"&gt;&lt;img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="MIT License"&gt;&lt;/a&gt;&lt;br&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/bbcd831059b7bf27d67a3a5eda876823f49ceae7f294408c2cae1c9f19c63687/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667"&gt;&lt;img src="https://camo.githubusercontent.com/bbcd831059b7bf27d67a3a5eda876823f49ceae7f294408c2cae1c9f19c63687/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667" alt="Platforms"&gt;&lt;/a&gt;&lt;br&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3adce1f628973855aca702ee1df09e0761c7c0c67b7400dde71dbab42c327dfe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6275696c74253230776974682d5461757269253230322d3234433844382e737667"&gt;&lt;img src="https://camo.githubusercontent.com/3adce1f628973855aca702ee1df09e0761c7c0c67b7400dde71dbab42c327dfe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6275696c74253230776974682d5461757269253230322d3234433844382e737667" alt="Built with Tauri"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Pixora is a free, open-source desktop app for image processing. Convert formats, resize, remove backgrounds with AI, and strip metadata — all 100% locally on your machine, with no internet required after setup.&lt;/p&gt;


  
    

    &lt;span class="m-1"&gt;app.mp4&lt;/span&gt;
  

  

  


&lt;p&gt;Built by &lt;a href="https://norbertok.com" rel="nofollow noopener noreferrer"&gt;Norberto Krucheski&lt;/a&gt;.&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Download&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Installers are automatically built for every release via GitHub Actions.&lt;/p&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Download&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;⬇ Download for Windows (.exe)&lt;/a&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;
&lt;br&gt;
&lt;strong&gt;macOS&lt;/strong&gt; (Apple Silicon M1 or higher)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;⬇ Download for macOS (.dmg)&lt;/a&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;a href="https://github.com/NorbertOSK/pixora/releases/latest" rel="noopener noreferrer"&gt;⬇ Download for Linux (.AppImage / .deb)&lt;/a&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just download, install, and run — no account, no setup, no cloud.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Format Conversion&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Convert between WebP, JPEG, and PNG&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Quality Control&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Adjustable quality slider (1–100%)&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;Smart Resize&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;10 built-in presets (hero, blog, avatar, 4K…) + custom dimensions. Aspect ratio always preserved.&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;EXIF &amp;amp; Metadata&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;View full metadata (camera, GPS, date, exposure…) and strip&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NorbertOSK/pixora" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





</description>
      <category>rust</category>
      <category>react</category>
      <category>tauri</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Mobile First - React Styled-Components - CSS Grid</title>
      <dc:creator>Norberto Krucheski</dc:creator>
      <pubDate>Thu, 02 Sep 2021 01:13:49 +0000</pubDate>
      <link>https://forem.com/norbertok/mobile-first-react-styled-components-css-grid-23p0</link>
      <guid>https://forem.com/norbertok/mobile-first-react-styled-components-css-grid-23p0</guid>
      <description>&lt;p&gt;A la hora de comenzar un proyecto web, ya sea una app o un sitio, si el mismo debe ser responsive, generalmente puede surgir la pregunta; &lt;strong&gt;¿en que resolución comenzar el proyecto?&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Como su nombre lo indica &lt;strong&gt;mobile first «los móviles primero»&lt;/strong&gt;, resume perfectamente esta filosofía de diseño.&lt;/p&gt;

&lt;p&gt;Se refiere a un modo de diseñar que tenga en cuenta, en primera instancia, un dispositivo móvil.&lt;/p&gt;

&lt;p&gt;A la hora de diseñar, podemos optar por usar frameworks como; Boostrap, Tailwind (el mejor 😁), o hacerlo de forma manual.&lt;/p&gt;

&lt;p&gt;En esta guía quiero enseñarte una forma sencilla de encarar el diseño utilizando CSS Grid, Areas y Templates, una vez que definimos la maqueta de nuestro sitio, se puede hacer un diseño responsive de forma muy sencilla.&lt;/p&gt;

&lt;p&gt;Queremos lograr una diseño responsive como este:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xrlghmehq4o4myradtz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xrlghmehq4o4myradtz.gif" alt="Diseño Responsive" width="760" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para comenzar creamos un proyecto de react y luego instalamos &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled-components.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create-react-app first-mobile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save styled-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejecutamos nuestro proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo primero que vamos hacer es eliminar los archivos que no utilizamos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App.css&lt;/li&gt;
&lt;li&gt;App.test.js&lt;/li&gt;
&lt;li&gt;logo.svg&lt;/li&gt;
&lt;li&gt;reportWebVitals.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NOTA:&lt;/strong&gt; El archivo &lt;strong&gt;index.css&lt;/strong&gt; trae unos estilos por defecto para react, estos los utilizaremos con &lt;strong&gt;styled-components&lt;/strong&gt; y luego borraremos el archivo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqh1nhlp4xjtep9hqrwm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqh1nhlp4xjtep9hqrwm0.png" alt="repositorio react Limpio" width="257" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Editamos los archivos &lt;strong&gt;index.js&lt;/strong&gt; y &lt;strong&gt;App.js&lt;/strong&gt; para que no nos de errores, deben de quedar así:&lt;/p&gt;

&lt;p&gt;App.js&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyamhau3rm6yg1py4r4u4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyamhau3rm6yg1py4r4u4.png" alt="repositorio react Limpio" width="620" height="624"&gt;&lt;/a&gt;&lt;br&gt;
index.js&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz7djlydhx8vu7e81v7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz7djlydhx8vu7e81v7w.png" alt="repositorio react Limpio" width="800" height="585"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Temas que vamos a ver:
&lt;/h2&gt;

&lt;p&gt;React con Styled-Components&lt;br&gt;
CSS Grid + Grid Area&lt;/p&gt;
&lt;h2&gt;
  
  
  React con Styled-Components&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Este módulo nos permite estilizar nuestros componentes, se considera &lt;code&gt;buenas practicas&lt;/code&gt; definir a que componente le corresponde que estilo.&lt;/p&gt;

&lt;p&gt;Lo mejor de &lt;strong&gt;styled-componentes&lt;/strong&gt;, es que nos permite escribir nuestro CSS de toda la vida, pero también es posible combinarlo con framworks como Tailwind.&lt;/p&gt;

&lt;p&gt;Otra ventaja de styled-componentes; es que nos genera clases automáticas, y es imposible que nuestras clases entren en conflicto entre ellas.&lt;/p&gt;

&lt;p&gt;Vamos a comenzar con escribir los estilos globales para toda la app (lo que teníamos en index.css).&lt;/p&gt;

&lt;p&gt;Para hacerlo de una forma mas ordenada, crearemos dentro de la carpeta &lt;strong&gt;src&lt;/strong&gt;, una carpeta llamada &lt;strong&gt;styles&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Creamos un archivo llamado &lt;strong&gt;globalStyles.js&lt;/strong&gt;, importamos &lt;strong&gt;createGlobalStyle&lt;/strong&gt; para crear estilos globales.&lt;/p&gt;

&lt;p&gt;Creamos un componente llamado &lt;strong&gt;GlobalStyle&lt;/strong&gt;, donde entre bastics (esa comillas simples invertidas) pegamos el cógido de &lt;strong&gt;index.css&lt;/strong&gt; (luego podemos borrar el index.css).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`

//Estilos por defecto que trae React
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Importamos este componente en el nivel mas alto de la app, en nuestro caso en &lt;strong&gt;App.js&lt;/strong&gt;, debe quedar así:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F347fiw2myx7pl1bcix8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F347fiw2myx7pl1bcix8a.png" alt="Global Style React Styled Components" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora vamos escribir los componentes para maquetar nuestro sitio y se vea de esta forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5pnfi2we6up4oayrur05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5pnfi2we6up4oayrur05.png" alt="React Styled Components" width="412" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pero vamos hacerlo directamente con &lt;strong&gt;styled-components&lt;/strong&gt;.&lt;br&gt;
Dentro de la carpeta &lt;strong&gt;styles&lt;/strong&gt;, creamos otro archivos llamados &lt;strong&gt;model.js&lt;/strong&gt;, (la idea es modelar el sitio).&lt;/p&gt;

&lt;p&gt;Importamos styled de styled-componentes, y generamos nuestro primer componente estilizado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ajl4cp9rny2kgx3oi19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ajl4cp9rny2kgx3oi19.png" alt="Primer componente styled-componentes" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como se puede ver, se crea un componente (Mayúscula), y de &lt;strong&gt;styled&lt;/strong&gt; utilizamos un &lt;strong&gt;div&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Styled&lt;/strong&gt; = contiene todas las etiquetas HTML.&lt;/p&gt;

&lt;p&gt;Vamos a proceder a crear el resto de componentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
width: 90%;
max-width: 1000px;
margin:20px auto;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="s2"&gt;`
background: blue;
color: #fff;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="s2"&gt;`
padding-left: 2%;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Sidebar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aside&lt;/span&gt;&lt;span class="s2"&gt;`
background: orange;
min-height: 100px;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`

background: orchid;
height: 100px;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;footer&lt;/span&gt;&lt;span class="s2"&gt;`
padding: 20px;
background: maroon;
color: #fff;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora vamos a importar nuestros componentes en &lt;strong&gt;App.js&lt;/strong&gt; y le vamos asignar una &lt;strong&gt;className&lt;/strong&gt; adicional que usaremos en un futuro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/globalStyles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Sidebar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles/model&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contenedor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contenido&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Test&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Lorem&lt;/span&gt; &lt;span class="nx"&gt;asdasd&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Sidebar&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sidebar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Sidebar&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Sidebar&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Widget&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widget-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Widget&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Widget&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widget-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Widget&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;footer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Footer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Footer&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si vemos nuestro proyecto actual, no tiene mucho estilo que digamos, solo sigue el orden jerarquizo de la etiquetas HTML.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpv0txluqmtwaa9otf2d3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpv0txluqmtwaa9otf2d3.png" alt="React Styled Components" width="397" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS Grid + Grid Area&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para trabajar en Grid, lo que necesitamos es definir una grilla en donde acomodamos nuestro diseño, muchos frameworks usan el sistema de columnas y filas para posicionar objetos en la grilla, nosotros lo haremos de forma manual. 💪&lt;/p&gt;

&lt;p&gt;Mi idea no es explicar CSS Grid a fondo 😢 , si no mostrar la magia de &lt;strong&gt;Grid Area&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En nuestro ejemplo, nuestro diseño cuenta con 3 columnas, y filas automáticas según el contenido.&lt;/p&gt;

&lt;p&gt;Vamos a actualizar el código del componente &lt;strong&gt;Container&lt;/strong&gt;, y automáticamente ya tendremos grid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
width: 90%;
max-width: 1000px;
margin:20px auto;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, auto);
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq46i1w3a4wqdie9njqr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq46i1w3a4wqdie9njqr6.png" alt="grid area css" width="405" height="717"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ya tenemos una grilla, pero aun no un diseño responsive que se adapte a cualquier resolución.&lt;/p&gt;

&lt;p&gt;Es aquí donde aparece &lt;strong&gt;grid area&lt;/strong&gt;. Literalmente, nos permite definir con áreas nuestros elementos HTML, a cada componente que creamos, le asignamos un área, debe quedar así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
width: 90%;
max-width: 1000px;
margin:20px auto;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, auto);
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="s2"&gt;`
background: blue;
color: #fff;
grid-area: header; //área

&amp;amp; &amp;gt; h1 {
    margin-left: 2%;
}

`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="s2"&gt;`
padding-left: 2%;
grid-area: contenido; //área
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Sidebar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aside&lt;/span&gt;&lt;span class="s2"&gt;`
background: orange;
min-height: 100px;
grid-area: sidebar; //área

/*flexbox para acomodar elementos*/

display: flex;
align-items: center;
justify-content: center; //área
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`

background: orchid;
height: 100px;
grid-area: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widget-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widget-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widget-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; //área

/*flexbox para acomodar elementos*/

display: flex;
align-items: center;
justify-content: center;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;footer&lt;/span&gt;&lt;span class="s2"&gt;`
padding: 20px;
background: maroon;
color: #fff;
grid-area: footer; //área
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTA&lt;/strong&gt;: En el componente Widget por medio de props, podemos asignarle un valor condicional (otra ventaja de styled components).&lt;/p&gt;

&lt;p&gt;Una vez que ya tenemos las áreas definidas, tenemos que utilizar &lt;strong&gt;grid-template-area&lt;/strong&gt;, para &lt;strong&gt;escribir nuestro diseño&lt;/strong&gt;, esto lo hacemos en el archivo &lt;strong&gt;globalStyles.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F691stfqhktas53b1jtii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F691stfqhktas53b1jtii.png" alt="grid template area" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como se puede ver, nuestro tamplate, esta basado en 3 columnas (nuestra grilla), solo debemos asignar nuestros componentes al área que deseamos, siempre respetando las 3 columnas para nuestro ejemplo.&lt;/p&gt;

&lt;p&gt;Ahora lo que resta es aplicar los diferenntes templates para las diferentes resoluciones, en nuestro caso, como estamos trabajando con la filosofía &lt;strong&gt;&lt;em&gt;mobile-first&lt;/em&gt;&lt;/strong&gt;, creamos las áreas de menor a mayor resolución.&lt;/p&gt;

&lt;p&gt;Para esto usamos los &lt;strong&gt;media-queries&lt;/strong&gt; de toda la vida en &lt;strong&gt;CSS&lt;/strong&gt;.&lt;br&gt;
En cada resolución, aplicamos un &lt;strong&gt;grid-template-area&lt;/strong&gt;, y redibujamos nuestro diseño.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`

//Estilos por defecto que trae React
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}


//Estilos para Grid Area

/*Grid Area First Mobile*/

/*min 640px*/
.contenedor {
grid-template-areas: "header header header"
                    "contenido contenido contenido"
                    "sidebar sidebar sidebar"
                    "widget-1 widget-1 widget-1"
                    "widget-2 widget-2 widget-2"
                    "footer footer footer"
;
}


/*min 768px*/
@media screen and (min-width: 768px){
.contenedor{
grid-template-areas:    "header header header"
                        "contenido contenido contenido"
                        "sidebar sidebar sidebar"
                        "widget-1 widget-1 widget-2"
                        "footer footer footer"
;
}    
}

/*min 1024px*/
@media screen and (min-width: 1024px){
.contenedor{
grid-template-areas:    "header header header"
                        "contenido contenido sidebar"
                        "widget-1 widget-2 sidebar"
                        "footer footer footer"
;
}

}

/*min 1280px*/
@media screen and (min-width: 1280px){
.contenedor{
grid-template-areas:    "header header header"
                        "contenido contenido sidebar"
                        "widget-1 widget-1 sidebar"
                        "widget-2 widget-2 sidebar"
                        "footer footer footer"
;
}

}

/*min 1536px*/

`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, solo creamos la estructura de nuestro sitio, pero una vez que rellenamos con nuestro contenido, podemos alinear contenido con flexbox como se muestra en el el ejemplo, en resumen, se puede utilizar el CSS de toda la vida, o combinarlo con otros framworks.&lt;/p&gt;

&lt;p&gt;La idea principal es armar una maqueta que sea responsive, luego el contenido de cada área, se debe trabajar por separado, pero si se combina con flexbox, o subgrid, los componentes se puede manipular sin problemas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo&lt;/strong&gt;: &lt;a href="https://github.com/NorbertOSK/React-StyledComponent-CSS-GridArea" rel="noopener noreferrer"&gt;React-StyledComponent-CSS-GridArea&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gracias&lt;br&gt;
Norberto.&lt;/p&gt;

</description>
      <category>mobilefirst</category>
      <category>react</category>
      <category>cssgrid</category>
      <category>styledcomponents</category>
    </item>
  </channel>
</rss>
