Web Server with HTML and CSS using OPTA

Hello everyone, I saw some tutorials using ESP32 or 8266 to create a Web Server with HTML and CSS. I'm trying to replicate the same thing for Arduino OPTA. I was successful in communicating with the Web Server and can issue commands normally.
My only doubt and problem is in the styling of this Web page, where I separated the C++, HTML and CSS programming files, and for HTML and CSS they have the extension ".h". Whenever I try to make a change to the CSS in the programming, my Web page doesn't receive these changes, it always stays the "standard" way.
I tried several ways, I don't know if there's something wrong with the programming or something else, I ask for the community's help so we can try to find a solution.
Remember that no error appears for me in the output, the commands work perfectly, the problem is in the styling.

File with C++ programming:

#include <SPI.h>
#include <PortentaEthernet.h>
#include <Ethernet.h>
#include "webpage.h"
#include "styles.h"

// The IP address will be dependent on your local network:
IPAddress ip(192, 168, 1, 177);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

// LED pin
const int ledPin = LED_D0;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // Initialize LED pin
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW); // Start with LED off

  // Start the Ethernet connection and the server:
  Ethernet.begin(ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // Start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // Listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    boolean currentLineIsBlank = true;
    String currentLine = ""; // Make a String to hold incoming data from the client

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        currentLine += c;

        if (c == '\n' && currentLineIsBlank) {
          // Handle LED control
          if (currentLine.indexOf("GET /LEDON") >= 0) {
            digitalWrite(ledPin, HIGH); // Turn LED on
          }
          if (currentLine.indexOf("GET /LEDOFF") >= 0) {
            digitalWrite(ledPin, LOW); // Turn LED off
          }

          // Serve the HTML page
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // The connection will be closed after completion of the response
          client.println();
          client.print(generateHTML());
          break;
        }

        if (c == '\n') {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    
    // Serve the CSS file
    if (currentLine.indexOf("GET /style.css") >= 0) {
      Serial.println("Serving CSS");
      sendCSS(client);
    }

    // Give the web browser time to receive the data
    delay(1);
    // Close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

void sendCSS(EthernetClient client) {
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/css");
  client.println("Connection: close");
  client.println("Cache-Control: no-cache, no-store, must-revalidate");
  client.println("Pragma: no-cache");
  client.println("Expires: 0");
  client.println();
  client.print(CSS_page);
}

File with HTML programming:

// webpage.h
#ifndef WEBPAGE_H
#define WEBPAGE_H

String generateHTML() {
  String html = R"====(
<!DOCTYPE HTML>
<html>
<head>
  <title>Arduino Web Server</title>
  <link rel="stylesheet" type="text/css" href="/style.css?v=
  )====";
  html += String(millis());  // Adiciona o timestamp atual para evitar cache
  html += R"====(
">
</head>
<body>
  <h1>Arduino Web Server</h1>
  <form action="/LEDON" method="GET">
    <button class="on" type="submit">Turn ON LED</button>
  </form>
  <form action="/LEDOFF" method="GET">
    <button class="off" type="submit">Turn OFF LED</button>
  </form>
</body>
</html>
)====";
  return html;
}

#endif

File with CSS programming:

// styles.h
#ifndef STYLES_H
#define STYLES_H

const char CSS_page[] PROGMEM = R"====(
body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
button { padding: 15px 25px; font-size: 16px; margin: 10px; border: none; border-radius: 5px; cursor: pointer; }
.on { background-color: #4CAF50; color: white; }
.off { background-color: #f44336; color: white; }
)====";

#endif

Despite all that, if you do a Force Reload -- usually by holding Shift while clicking on Refresh in the toolbar or in addition to the key sequence -- does that serve the file again and fix it?

You might also check the Network monitor and verify if the request is going to cache, what is being seen as the response, etc

I had similar issue, turned out that i had preloaded page layout and forgot to refresh after every change

I did some tests with Reload, but I was also unsuccessful.
I checked my serial monitor and it seems that it is sending the CSS to the Cache normally.
I also verified that the updated code in the programming CSS is appearing in the Web Page inspection as shown in the images below, but the code that is there is not updated on the Web Page, even though it is there, it does not update the interface.

I'm really trying to understand this problem but I can't find a solution. I did a test containing the HTML, CSS and C++ files together in a single file and whenever I update the CSS my page also updates with the new changes in the interface, but the code is very difficult to read, understand, it's very dirty.

That last screenshot of the Network monitor shows the problem. For the style.css request, the response is both HTML content, and then the HTTP headers and content for the CSS. (All those headers being sent were not even being seen as headers, just invalid CSS.) This is because of the structure of the code in the loop, which calls both generateHTML before and sendCSS after the condition

is evaluated as true. The code needs to be restructured so that only one response (with headers and content) is sent each time through the loop, between the client = server.available() and the client.stop()

BTW, the indexOf check is too lenient. It should really be more like

if (currentLine.startsWith("GET /style.css")) {

Do you understand why?

you say that tdbstore can be used to save html, css, js pages like on esp?